【问题标题】:C# MVVM: MenuItem Command don´t execute in ViewModelC# MVVM:MenuItem 命令不在 ViewModel 中执行
【发布时间】:2019-10-09 15:37:16
【问题描述】:

我创建了一个 Delete MenuItem 并将一个命令绑定到它。 现在我遇到了问题,如果我按下 Delete MenuItem,什么也没有发生。此外,如果程序使用调试器执行,它永远不会到达私有 void DeleteItem。

xaml:

<ListBox.ItemTemplate>
            <DataTemplate>
                <Border Background="#F5F5F5" Width="80" Height="60" Margin="0,5,5,5">
                    <Border.ContextMenu>
                        <ContextMenu>
                            <MenuItem Header="Delete"
                                      Command="{Binding Path=DeleteItemCommand, RelativeSource={RelativeSource FindAncestor, AncestorType= MenuItem}}">
                                <MenuItem.Icon>
                                    <Label FontFamily="#FontAwesome" Content="&#xf1f8;" />
                                </MenuItem.Icon>
                            </MenuItem>
                        </ContextMenu>
                    </Border.ContextMenu>

视图模型:

public ICommand DeleteItemCommand { get; set; } 
DeleteItemCommand = new RelayCommand(DeleteItem);

private void DeleteItem(object obj)
{
    try
    {
        // Do Magic
    }
    catch (Exception)
    {
        MessageBox.Show(error);
    }
}

如果有人可以帮助我或对如何解决它有任何想法,那就太好了,因为我找不到错误。

【问题讨论】:

    标签: c# wpf mvvm


    【解决方案1】:

    ContextMenu 确实不是可视化树的一部分。但我认为由于这个原因,RelativeSource 将不起作用,因为绑定将查找数据上下文的可视化树。 contextMenu 不是该可视化树的一部分,因此它不会找到正确的数据上下文。我在过去使用窗口资源中的代理元素找到了解决方案。然后将此代理元素设置为窗口中隐藏内容控件的内容。在 menuItem 上,将 CommandBinding 设置为 Datacontext.DeleteCommand,并将源设置为静态资源代理元素。这有点hackish,但它有效。 所以要显示一些 xaml,试试这个: 首先在窗口的资源中创建一个frameworkelement,其datacontext设置为windows datacontext(viewmodel)

    <Window.Resources>
            <FrameworkElement x:Key="ProxyElement" DataContext="{Binding}"/>
    </Window.Resources>
    

    然后将资源用于折叠内容控件的内容。并设置正确绑定到 menuItem。像这样的:

     <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>
            <ContentControl Visibility="Collapsed" Content="{StaticResource ProxyElement}"/>
            <ListBox x:Name="lbTest" Grid.Row="1">
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <Border Background="#F5F5F5" Width="80" Height="60" Margin="0,5,5,5">
                            <Border.ContextMenu>
                                <ContextMenu>
                                    <MenuItem Header="Delete"
                                              Command="{Binding DataContext.DeleteCommand, Source={StaticResource ProxyElement}}">
                                        <MenuItem.Icon>
                                            <Label FontFamily="#FontAwesome" Content="&#xf1f8;" />
                                        </MenuItem.Icon>
                                    </MenuItem>
                                </ContextMenu>
                            </Border.ContextMenu>
                        </Border>
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>
    

    这应该可行。试试看吧。

    【讨论】:

      【解决方案2】:

      不确定这是否会有所帮助,但请尝试使用绑定而不是绑定路径。

      【讨论】:

      • 谢谢你的回答 :) 我已经试过了,可惜没用
      【解决方案3】:

      ContextMenu 不是 VisualTree 的一部分,这就是绑定失败的原因。您可以使用诸如 ContextMenu.PlacementTarget.Tag.Property 之类的中继作为绑定搜索的第二条线索的缓存。

              <ContextMenu>
                  <MenuItem Command="my:ImgTreeView.Folders" Header="Folders"
                                IsEnabled="{Binding Path=PlacementTarget.Tag.IsCheckFolder, RelativeSource={RelativeSource AncestorType=ContextMenu}}">
                      <MenuItem.Icon>
                              <Image Source="StarFolders.png" />
                      </MenuItem.Icon>
                  </MenuItem>
                  <!-- ... -->
              </ContextMenu>
      

      【讨论】:

      • 谢谢。我对 VisualTree 有点困惑。它还包含 ListBox 还是仅包含 TreeView?问候黑熊
      • ContextMenu 来自popup 框架元素的BAse 库,实际上,popup 是一个WPF Primitives Control。基元不会包含在可视化树中。
      猜你喜欢
      • 2021-06-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-26
      相关资源
      最近更新 更多