拨开荷叶行,寻梦已然成。仙女莲花里,翩翩白鹭情。
IMG-LOGO
主页 文章列表 从背景关系选单访问资料背景关系属性

从背景关系选单访问资料背景关系属性

白鹭 - 2022-01-23 1960 0 0

我尝试了解一下 listboxview 与背景关系选单相结合的作业原理,因此我撰写了以下 XAML 代码:

<UserControl>
   ...
     <ListView
                x:Name="level1Lister"
                Grid.Row="1"
                behaviours:AutoScrollListViewBehaviour.ScrollOnNewItem="True"
                ItemsSource="{Binding LogBuffer, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
                <ListView.ItemContainerStyle>
                    <Style TargetType="ListViewItem">
                        <Setter Property="Padding" Value="1" />
                        <Setter Property="Margin" Value="2,0" />
                        <Setter Property="BorderThickness" Value="0" />
                    </Style>
                </ListView.ItemContainerStyle>
                <ListView.ItemsPanel>
                    <ItemsPanelTemplate>
                        <StackPanel Orientation="Vertical" />
                    </ItemsPanelTemplate>
                </ListView.ItemsPanel>
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <StackPanel>
                            <StackPanel.ContextMenu>
                                <ContextMenu>
                                    <MenuItem Command="{Binding Path=DataContext.ValidateAllCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContextMenu}}, FallbackValue=9999999999}" Header="Copy" />
                                </ContextMenu>
                            </StackPanel.ContextMenu>
                            <TextBlock Foreground="{Binding Color, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Text="{Binding Message, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
                        </StackPanel>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
</UserControl>

我的主要问题是我无法访问我的“ValidateAllCommand”函式,出于某种原因......我认为它与“RelativeSource={RelativeSource FindAncestor ...”部分有关,但我无法弄清楚如何。

uj5u.com热心网友回复:

的“问题”ContextMenu在于它不是可视化树的一部分。原因是MenuItem使用 aPopup来托管内容。虽然Popup本身是可视化树的一部分,但其子内容在新Window实体中呈现时断开连接我们知道Window树中只能有一个,这Window必须是根。
由于Binding.RelativeSource遍历可视化树,从 的分离树内开始Popup,以查找系结源,因此Bindig无法决议。

Popup.Child内容继承DataContextPopup在 的情况下,ContextMenu这意味着或 从 的父级MenuItem继承,更准确地说。在您的方案是对资料模型DataContextContextMenuContextMenuDataContextListBoxItemDataContextDataTemplate

这意味着,一种解决方案可能是在项目模型中实作命令。

第二种解决方案是利用路由命令。在您的场景中,此解决方案可能更合理。路由命令/事件可以跨越两棵树之间的边界。

在以下示例中,我使用了ApplicationCommands.Copy命令,这是预定义的路由命令之一。MenuItem.Parameter被系结到DataContext,这是该项目的资料模型(从继承ContextMenu,如前所述)。这样命令处理程序就可以知道资料源。
事件处理程序可以使用该UIElement.CommandBindings属性附加到任何父元素在示例中,处理程序附加到ListBox元素:

主视窗.xaml

<ListBox>
  <ListBox.CommandBindings>
    <CommandBinding Command="{x:Static ApplicationCommands.Copy}"
                    Executed="CopyCommand_Executed" />
  </ListBox.CommandBindings>
  <ListBox.ItemTemplate>
    <DataTemplate DataType="{x:Type local:DataItem}">
      <StackPanel>
        <StackPanel.ContextMenu>
          <ContextMenu>
      
            <!-- 
              Here we are in a detached visual tree. 
              The DataContext is inherited from the ContextMenu element. 
              The framework allows routed events to cross the boundaries between the trees.
            -->
            <MenuItem Command="{x:Static ApplicationCommands.Copy}"
                      CommandParameter="{Binding}"
                      Header="Copy" />
          </ContextMenu>
        </StackPanel.ContextMenu>

        <TextBlock />
      </StackPanel>
    </DataTemplate>
  </ListBox.ItemTemplate>
</ListBox>

主视窗.xaml.cs

private void CopyCommand_Executed(object sender, ExecutedRoutedEventArgs e)
{
  var listBoxItemModel = e.Parameter as LogBufferItem;

  // TODO::Handle Copy command. For example:
  var commandTarget = this.DataContext as ICommandModel;
  commandTarget.ValidateAllCommand.Execute(listBoxItemModel);
}

第三个,但不推荐的解决方案是系结DataContext的的ContextMenu家长所关心的方面:

  <ListBox.ItemTemplate>
    <DataTemplate DataType="{x:Type local:DataItem}">
      <StackPanel>
        <!-- DataTemplate DataContext -->

        <Grid DataContext="{Binding RelativeSource={RelativeSource AncestorType=ListBox}, Path=DataContext}">

          <!-- ListBox DataContext -->
          <Grid.ContextMenu>
            <ContextMenu>
      
              <!-- 
                Here we are in a detached visual tree. 
                The DataContext is inherited from the ContextMenu/Grid element. 
              -->
              <MenuItem Command="{Binding ValidateAllCommand}"
                        Header="Copy" />
            </ContextMenu>
          </Grid.ContextMenu>
        </Grid>

        <!-- DataTemplate DataContext -->
        <TextBlock />
      </StackPanel>
    </DataTemplate>
  </ListBox.ItemTemplate>
</ListBox
标签:

0 评论

发表评论

您的电子邮件地址不会被公开。 必填的字段已做标记 *