微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

UWP:从 FlyoutMenuItem 点击处理程序中找到父级

如何解决UWP:从 FlyoutMenuItem 点击处理程序中找到父级

使用 UWP,我有一个 ListView,其中每个项目都包含一个 Button。点击按钮会打开一个 MenuFlyout。点击其中一个弹出选项会触发 Click 事件。

在事件处理程序中,我如何找到父 Button 或父 ListView 项?

这是我的 XAML 的摘录。具体来说,我想在 OnItemEdit 处理程序中找到“Note”元素。

<Page.Resources>
  <ResourceDictionary>

    <DataTemplate x:Key="NoteItemTemplate">
      <Grid>
        <Grid.ColumnDeFinitions> ... </Grid.ColumnDeFinitions>
        <TextBox Name="Note" />
        <Button>
          <Image Source="..." />
          <Button.Flyout>
            <MenuFlyout>
              <MenuFlyoutItem Text="Edit" Click="OnItemEdit" />
              <MenuFlyoutItem Text="Delete" Click="OnItemDelete" />
            </MenuFlyout>
          </Button.Flyout>
        </Button>

      </Grid>
    </DataTemplate>
    ...
    <local:DetailItemSelector x:Key="DetailItemSelector"
      NoteItemTemplate="{StaticResource NoteItemTemplate}"
      ...
    />

  </ResourceDictionary>
</Page.Resources>

<ListView
  x:Name = "DetailList"
  ItemsSource = "{x:Bind DetailListItems}"
  ItemTemplateSelector = "{StaticResource DetailItemSelector}">
</ListView>

处理程序定义为:

async void OnItemEdit(object sender,RoutedEventArgs e)
{
  ...
}

编辑 - 解决

如果没有更好的方法,这里有一个还不错的解决方法。诀窍是使用 FlyoutBase.AttachedFlyout 而不是 Button.Flyout

    <DataTemplate x:Key="NoteItemTemplate">
      <Grid>
        <Grid.ColumnDeFinitions> ... </Grid.ColumnDeFinitions>

        <TextBox ... Name="Note" />

        <Button ... Click=="onMoreClicked">
          <Image Source="..." />
          FlyoutBase.AttachedFlyout
            <MenuFlyout>
              <MenuFlyoutItem Text="Edit" Click="OnItemEdit" />
              <MenuFlyoutItem ... />
            </MenuFlyout>
          </FlyoutBase.AttachedFlyout>
        </Button>

      </Grid>
    </DataTemplate>

而且,后面的代码

FrameworkElement lastItemTapped = null;

public void onMoreClicked (object sender,RoutedEventArgs e)
{
  Button button = sender as Button;

  // find parent list item containing button
  DependencyObject element = button;
  while (element != null)
  {
    if (element is FrameworkElement && (element as FrameworkElement).Name.Equals("Item"))
      break;
    element = VisualTreeHelper.GetParent(element);
  }
  if (element != null)
    lastItemTapped = element as FrameworkElement;

  // show flyout menu
  FlyoutBase.ShowAttachedFlyout(button);
}

public void OnItemEdit(object sender,RoutedEventArgs e)
{
  if (lastItemTapped == null)
    return;
  ...
}

解决方法

具体来说,我想在 OnItemEdit 处理程序中找到“Note”元素。

假设 DataTemplate 应用于“注释”,这应该就像将 DataContext 参数的 sender 转换为 Note(或任何您的类型被调用):

private void OnItemEdit(object sender,RoutedEventArgs e)
{
    MenuFlyoutItem menuFlyoutItem = (MenuFlyoutItem)sender;
    var note = menuFlyoutItem.DataContext as YourNoteClass;
    ...
}

如果您需要对“节点”TextBox 元素的引用,您可以在可视化树中找到它:

private void OnItemEdit(object sender,RoutedEventArgs e)
{
    MenuFlyoutItem menuFlyoutItem = (MenuFlyoutItem)sender;
    DependencyObject container = DetailList.ContainerFromItem(menuFlyoutItem.DataContext);
    TextBox note = FindVisualChild<TextBox>(container);
    ...
}

private static T FindVisualChild<T>(DependencyObject visual) where T : DependencyObject
{
    for (int i = 0; i < VisualTreeHelper.GetChildrenCount(visual); i++)
    {
        DependencyObject child = VisualTreeHelper.GetChild(visual,i);
        if (child != null)
        {
            T correctlyTyped = child as T;
            if (correctlyTyped != null)
                return correctlyTyped;

            T descendent = FindVisualChild<T>(child);
            if (descendent != null)
                return descendent;
        }
    }
    return null;
}
,

在您的方案中,您可以添加一个成员变量来保存表示 GridListViewItem 实例以供以后访问。将 PointerEntered 事件添加到 Grid 面板。当您单击某个项目的按钮以弹出一个浮出控件时,将首先触发该项目的 PointerEnteredGrid 事件处理程序。在 PointerEntered 事件处理程序中,将 sender 分配给成员变量。然后您可以访问 Grid 事件处理程序中的 OnItemEdit

您可以检查以下内容作为示例:

//MainPage.xaml
<DataTemplate x:Key="NoteItemTemplate">
  <Grid PointerEntered="Grid_PointerEntered" >
    <Grid.ColumnDefinitions> ... </Grid.ColumnDefinitions>
    ……
  </Grid>
</DataTemplate>

//MainPage.xaml.cs

private Grid myPanel;

private void Grid_PointerEntered(object sender,PointerRoutedEventArgs e)
{
    myPanel = sender as Grid;
}

private void OnItemEdit(object sender,RoutedEventArgs e)
{
    //Change the value of index to adjust your scenario
    var box = VisualTreeHelper.GetChild(myPanel,0) as TextBox;
}

更新:

请尝试以下代码:

private void OnItemEdit(object sender,RoutedEventArgs e)
{            
    //Find the item be clicked
    object clickedItem=new object();
    foreach(var cur in DetailList.Items)
    {
        if(cur.ToString()==(sender as MenuFlyoutItem).DataContext.ToString())
        {
            clickedItem = cur;
            break;
        }
    }
    //
    var type = DetailList.ContainerFromItem(clickedItem);
    var item = type as ListViewItem;
    var box = VisualTreeHelper.GetChild(item.ContentTemplateRoot as DependencyObject,0);
    string text = (box as TextBox).Text;
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?