1

我正在使用 GridView 构建 Windows 8 Metro 应用程序(C#、XAML),并且我想在用户单击的 GridViewItem 附近显示一个弹出窗口。我计划通过单击事件参数获取 GridViewItem UIElement 并使用它的坐标来确定放置我的弹出窗口的位置。

但是,我还没有找到一种方法来获取对被点击的实际 GridViewItem UIElement 的引用!我在下面尝试过的事件似乎只通过它们的 EventArgs 公开 DataContext,而不是实际的 UIElement:

object sender // is the GridView
ItemClickEventArgs.ClickedItem // is the DataContext of the GridViewItem
ItemClickEventArgs.OriginalSource // is the GridView
SelectionChangedEventArgs.OriginalSource // is null
SelectionChangedEventArgs.AddedItems.First() // is the DataContext of the GridViewItem

如果重要的话,我的 GridView.ItemSource 是一个 CollectionViewSource,它的 Source 绑定到一个视图模型的集合。

是否可以通过我忽略的某些事件来获取单击的 GridViewItem?如果不是,我应该从什么角度来解决它?我至少可以通过 PointerPressed 事件获得相对于 GridView 的点击坐标,并查看我可以做些什么来以这种方式定位项目,但真的希望我不必走那条路。

4

2 回答 2

6

我还在应用程序中实现了这种行为 - 使用 Callisto 库中的 Flyout 弹出窗口和单击的 GridViewItem。

简单地调用 ContainerFromItem 来获取相关的 GridViewItem 控件要容易得多:

private void itemGridView_ItemClick(object sender, ItemClickEventArgs e)
{
    var clickedItem = itemGridView.ItemContainerGenerator.ContainerFromItem(e.ClickedItem);

    // Open the flyout now
    Flyout flyOut = new Flyout();
    if (clickedItem is GridViewItem)
        flyOut.PlacementTarget = clickedItem as UIElement;
    else
        flyOut.PlacementTarget = sender as UIElement;

    flyOut.Placement = PlacementMode.Left;
    SolidColorBrush br = new SolidColorBrush(Colors.Blue);
    flyOut.Background = br;
    TextBlock tb = new TextBlock();
    tb.Text = "I'm in your flyout messing with your text";

    flyOut.Content = tb;
    flyOut.IsOpen = true;
}

感谢这里的这个帖子为我指明了正确的方向。

于 2012-09-01T16:36:20.710 回答
0

VisualTreeHelper 可能会帮助您将其放置到 GridView/GridViewItem 并找到它的子/父,如果您想找到 UIElement。要确定在容器内单击了什么 UIElement,应使用VisualTreeHelper解决。

有关 VisualTreeHelper 的更多信息,请参见此处Visual Tree Helper 示例

如果您不想使用 VisualTreeHelper,我会创建一个附加属性,我所有的 GridViewItem 单击都将作为依赖对象传递给 GridView 的附加属性(这是自定义的,您可以从中获得更多)。

于 2012-08-02T17:44:18.493 回答