C#MVVM:MenuItem命令不在ViewModel中执行

时间:2019-05-23 05:55:18

标签: c# wpf mvvm

我创建了一个Delete MenuItem并将命令绑​​定到该菜单项。 现在,我遇到了问题,如果按Delete DeleteItem,则什么也不会发生。同样,如果程序是用调试器执行的,则它永远不会到达私有的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>

ViewModel:

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

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

如果有人可以帮助我或对解决该问题有任何想法,那将非常好,因为我找不到错误。

3 个答案:

答案 0 :(得分:0)

不确定是否有帮助,但尝试使用“绑定”而不是“绑定路径”。

答案 1 :(得分:0)

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>

答案 2 :(得分:0)

ContextMenu确实不是视觉树的一部分。但是我认为由于这个原因,RelativeSource将无法工作,因为绑定将查找数据上下文的可视树。 contextMenu不是该可视树的一部分,因此它将找不到正确的datacontext。我过去使用窗口资源中的proxy元素找到了解决方案。然后将此代理元素设置为窗口中隐藏的contentcontrol的内容。在menuItem上,将CommandBinding设置为Datacontext.DeleteCommand,将源设置为静态资源proxyelement。它有点黑,但是可以用。 因此,要显示一些xaml,请尝试以下操作: 首先在窗口的资源中创建一个框架元素,并将datacontext设置为windows datacontext(视图模型)

<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>

这应该有效。试试看。