我正在尝试获取一个元素来触发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事件?
P.S。我也在app-hub表单上发布了这个,但还没有回复:http://forums.create.msdn.com/forums/p/98004/584400.aspx
答案 0 :(得分:2)
解决此问题的一种方法是使用TouchFrame侦听TouchAction.Up。您必须使用TouchPoints的位置属性计算ButtonUp协同使用的UIElement,如下所述: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
答案 1 :(得分:2)
我的解决方案有点像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
属性。 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>
答案 2 :(得分:1)
上次检查时,我的手机没有连接鼠标。
使用Tap
事件代替MouseLeftButtonUp
。对于更复杂的手势,请使用Silverlight Toolkit GestureListener
类。
答案 3 :(得分:0)