Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/jsf/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
UWP:从弹出菜单项单击处理程序查找父项_Uwp_Flyout - Fatal编程技术网

UWP:从弹出菜单项单击处理程序查找父项

UWP:从弹出菜单项单击处理程序查找父项,uwp,flyout,Uwp,Flyout,使用UWP,我有一个列表视图,其中每个项目都包含一个按钮。点击该按钮将打开一个菜单out。点击其中一个弹出式选项将触发单击事件 在事件处理程序中,如何找到父按钮或父ListView项 这是我的XAML的摘录。具体来说,我想在OnItemEdit处理程序中查找“Note”元素 <Page.Resources> <ResourceDictionary> <DataTemplate x:Key="NoteItemTemplate">

使用UWP,我有一个
列表视图
,其中每个项目都包含一个
按钮
。点击该按钮将打开一个
菜单out
。点击其中一个弹出式选项将触发
单击事件

在事件处理程序中,如何找到父按钮或父
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>
编辑-解决方案

如果没有更好的办法,这里有一个解决办法也不错。诀窍是使用
弹出按钮base.AttachedFlyout
而不是
按钮.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>

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

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

//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;
}
具体地说,我想在Medit处理程序中查找“Note”元素

假设将
DataTemplate
应用于一个“Note”,这应该与将
sender
参数的
DataContext
转换为
Note
一样简单(或者无论您的类型被称为什么):

如果需要对“节点”
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;
}
private void-onite-medit(对象发送方,路由目标)
{
MenuFlyoutItem MenuFlyoutItem=(MenuFlyoutItem)发送方;
DependencyObject容器=DetailList.ContainerFromItem(menuFlyoutItem.DataContext);
TextBox note=FindVisualChild(容器);
...
}
私有静态T FindVisualChild(DependencyObject可视),其中T:DependencyObject
{
for(int i=0;i
我一定是误解了你的解释。如果列表中有10个项目,如何确定哪个项目(以及哪个文本框)触发了Onite Medit事件?看来你是任意挑选了一个(可能是第一个)。这不是任意的。在单击某个按钮弹出弹出型按钮之前,必须将指针移动到包含该弹出型按钮的ListViewItem上。此时,将调用PointerEntered事件处理程序将ListViewItem的网格分配给成员变量,并且在弹出按钮隐藏之前不会调用其他ListViewItem的PointerEntered事件处理程序。当您单击ListViewItem的按钮时,这可以确保存储在成员变量中的网格始终是其按钮被单击的网格。啊,对不起,我显然不明白“PointerEntered”的作用。不幸的是,我认为这种方法行不通。我没有提到(因为我认为会有一个直截了当的解决方案)它需要与触摸屏一起工作,我不认为“指针连接”会起到任何作用(我将对此进行测试并查看)。正确的解决方案是处理“按钮”单击事件,缓存对按钮(或父项)的引用,然后将单击事件转发给原始处理程序。我找不到办法。另外,“指针式”方法有些脆弱。我已经更新了答案,您可以尝试看看更新是否能满足您的要求。我已经有了解决方法,我认为这更好。我会把它添加到OP中作为参考。@PeriHartman:你试过这个吗?对不起,还没有。我肯定会的。可能是星期四。如果我按照你的建议做,
DataContext
指向注释数据(一个文本字符串),而不是注释文本框。我已经对此进行了研究和试验,但不知道如何将
DataContext
设置为note控件。我尝试将
DataContext=“{StaticResource Item}”
添加到“编辑”
MenuFlyoutItem
,但这导致运行时异常。对于这种情况,在线搜索没有发现任何结果。我想我可以使用搜索
ListView
来搜索包含引用注释数据的项目。很简单,但我只想在没有更直接的解决方案时这样做。@PeriHartman:请参阅我的编辑。它应该能回答你的问题。
//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;
}
private void OnItemEdit(object sender, RoutedEventArgs e)
{
    MenuFlyoutItem menuFlyoutItem = (MenuFlyoutItem)sender;
    var note = menuFlyoutItem.DataContext as YourNoteClass;
    ...
}
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;
}