我正在尝试让一个元素在用户单击/点击它的外部,拖入它,然后开始操作时触发MouseUp事件。这种类型的功能在Silverlight中有效,但在WP7中无效。我不知道如何让它在WP7中工作。
我创建了一个简单的应用程序来演示这一点。在一个全新的WP7应用程序中,我在内容面板中添加了以下内容:
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid x:Name="g1" MouseLeftButtonUp="Grid_MouseLeftButtonUp" Background="Green" />
<Grid x:Name="g2" Grid.Row="1" MouseLeftButtonUp="Grid_MouseLeftButtonUp" Background="Blue" />
</Grid>然后是代码背后的Grid_MouseLeftButtonUp处理程序:
private void Grid_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
System.Diagnostics.Debug.WriteLine("MouseUp in " + (sender as Grid).Name);
(sender as Grid).Background = new SolidColorBrush(Colors.Red);
}运行此应用程序,请注意,如果您在按下的同一单元格中释放按钮,则MouseUp事件会正常触发,但如果您从一个单元格拖动到另一个单元格,则不会触发该事件。如何触发MouseUp事件?
附言:我也在应用程序中心的表单上发布了这个,但还没有回应:http://forums.create.msdn.com/forums/p/98004/584400.aspx
发布于 2012-01-08 17:57:55
我的解决方案有点像ShawnFeatherly的,但没有TouchFrame。
基本上,正如他所说,如果从发生MouseDown事件的网格调用MouseCapture,MouseUp将在同一网格上触发。因此,我们知道当MouseUp发生时如何得到通知,剩下的唯一问题是如何知道MouseUp实际发生在哪个网格中。为此,我们将使用VisualTreeHelper.FindElementsInHostCoordinates方法,因为它返回指定坐标处的所有元素。
因此,首先向每个网格添加一个MouseLeftButtonDown事件处理程序:
private void Grid_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
((Grid)sender).CaptureMouse();
}现在,在每个网格的MouseLeftButtonUp事件处理程序中,首先释放鼠标捕获,然后检索发生MouseUp的网格:
private void Grid_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
var grid = (Grid)sender;
grid.ReleaseMouseCapture();
var mouseUpGrid = VisualTreeHelper.FindElementsInHostCoordinates(e.GetPosition(this), this.ContentPanel)
.OfType<Grid>()
.FirstOrDefault();
if (mouseUpGrid != null)
{
Debug.WriteLine("MouseUp in " + mouseUpGrid.Name);
mouseUpGrid.Background = new SolidColorBrush(Colors.Red);
}
}请注意,根据可视化树的不同,可能会出现问题:如果您有多个网格,并且只想检测其中一些网格上的MouseUp,则需要一种方法来识别它们。为此,我建议使用Tag属性。标记是每个控件上可用的通用字段,您可以根据需要使用它。它对于身份识别特别有用。
首先将其添加到您感兴趣的网格中:
<Grid x:Name="ContentPanel"
Grid.Row="1"
Margin="12,0,12,0"
MouseLeftButtonUp="ContentPanel_MouseLeftButtonUp">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid x:Name="g1"
Background="Green"
MouseLeftButtonDown="Grid_MouseLeftButtonDown"
MouseLeftButtonUp="Grid_MouseLeftButtonUp"
Tag="dragdrop" />
<Grid x:Name="g2"
Grid.Row="1"
Background="Blue"
MouseLeftButtonDown="Grid_MouseLeftButtonDown"
MouseLeftButtonUp="Grid_MouseLeftButtonUp"
Tag="dragdrop" />
</Grid>然后在代码隐藏中使用完全相同的逻辑,但这次在浏览可视化树时添加一个过滤器:
private void Grid_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
var grid = (Grid)sender;
grid.ReleaseMouseCapture();
var mouseUpGrid = VisualTreeHelper.FindElementsInHostCoordinates(e.GetPosition(this), this.ContentPanel)
.OfType<Grid>()
.FirstOrDefault(element => element.Tag is string && (string)element.Tag == "dragdrop");
if (mouseUpGrid != null)
{
Debug.WriteLine("MouseUp in " + mouseUpGrid.Name);
mouseUpGrid.Background = new SolidColorBrush(Colors.Red);
}
}你就完事了!这段代码应该能够处理复杂的场景,比如:
<Grid x:Name="ContentPanel"
Grid.Row="1"
Margin="12,0,12,0"
MouseLeftButtonUp="ContentPanel_MouseLeftButtonUp">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid x:Name="g1"
Background="Green"
MouseLeftButtonDown="Grid_MouseLeftButtonDown"
MouseLeftButtonUp="Grid_MouseLeftButtonUp"
Tag="dragdrop" />
<Grid x:Name="DummyGrid" Grid.Row="1">
<Grid x:Name="g2"
Background="Blue"
MouseLeftButtonDown="Grid_MouseLeftButtonDown"
MouseLeftButtonUp="Grid_MouseLeftButtonUp"
Tag="dragdrop" />
</Grid>
</Grid>发布于 2012-01-08 10:06:54
解决此问题的一种方法是侦听TouchAction.Up的TouchFrame。您必须使用TouchPoints的UIElement属性计算ButtonUp响应的位置,如下所述:http://forums.create.msdn.com/forums/p/98004/584465.aspx#584465
另一种方法是在ButtonDown UIElement中捕获鼠标。这将导致ButtonUp正确触发,但是发送者将是导致ButtonDown的原始UIElement。您可以使用MouseEnter和MouseLeave跟踪鼠标在其中移动的元素。这里简要介绍了鼠标捕获的必要性:http://forums.create.msdn.com/forums/p/70785/431882.aspx
发布于 2012-01-08 08:51:37
据我所知,我的手机没有连接鼠标。
使用Tap事件而不是MouseLeftButtonUp。对于更复杂的手势,请使用Silverlight Toolkit GestureListener类。
https://stackoverflow.com/questions/8773237
复制相似问题