在Listview MenuItem MVVM中执行命令

时间:2019-05-02 01:30:44

标签: c# wpf listview mvvm menuitem

为什么列表视图菜单项中的命令没有执行?

这是我的列表视图中的代码

<ListView ItemsSource="{Binding ListDataCorrection}"  >
            <ListView.View>
                <GridView>
                    <GridViewColumn Header="Validate">
                        <GridViewColumn.CellTemplate>
                            <DataTemplate>
                                <Button Content="Update" Margin="5" Cursor="Hand" Command="{Binding RelativeSource={RelativeSource FindAncestor, 
                                        AncestorType={x:Type ListView}}, Path=DataContext.ValidateCommand}"/>
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>
                </GridView>
            </ListView.View>

            <ListView.ContextMenu>
                <ContextMenu>
                    <MenuItem Header="Remove" Command="{Binding RelativeSource={RelativeSource FindAncestor, 
                                        AncestorType={x:Type ListView}}, Path=DataContext.ValidateAllCommand}">
                    </MenuItem>
                </ContextMenu>
            </ListView.ContextMenu>
        </ListView>

但是奇怪的是在Gridview中执行了ValidateCommand。

菜单项中的命令不是。

我的装订怎么了?

我还检查了命令名称是否正确。如果没有,我应该收到一条错误消息,提示在ViewModel中找不到该命令

谢谢。

3 个答案:

答案 0 :(得分:0)

有时MenuItems中的ContextMenu也会出现此问题。我猜ContextMenu找不到正确的DataContext。

我的解决方法是一个BindingProxy类,如下所示:

public class BindingProxy : Freezable
{   
    public static readonly DependencyProperty DataProperty = DependencyProperty.Register(
        "Data", typeof (object), typeof (BindingProxy), new UIPropertyMetadata(null));

    /// <summary>
    ///     This Property holds the DataContext
    /// </summary>
    public object Data
    {
        get { return GetValue(DataProperty); }
        set { SetValue(DataProperty, value); }
    }

    protected override Freezable CreateInstanceCore()
    {
        return new BindingProxy();
    }
}

在视图的资源(UserControl或Window)中,您必须添加代理,例如:

<codeBase:BindingProxy x:Key="proxy" Data="{Binding}"/>

在您的MenuItem中,您可以将其用于:

<MenuItem Header="Remove" Command="{Binding Source={StaticResource proxy}, Path=Data.ValidateAllCommand}"/>

答案 1 :(得分:0)

菜单(例如弹出菜单)不是按需创建的可视树的一部分。由于它不是可视树的一部分,因此它将不会继承其父级DataContext。但是,您仍然可以使用绑定中的PlacementTarget属性绑定到ListView:

        <ListView.ContextMenu>
            <ContextMenu>
                <MenuItem Header="Remove" 
                          Command="{Binding Path=PlacementTarget.DataContext.ValidateAllCommand}">
                </MenuItem>
            </ContextMenu>
        </ListView.ContextMenu>

答案 2 :(得分:0)

  

为什么列表视图菜单项中的命令没有执行?

由于ListView不是MenuItem的视觉祖先,因此找不到绑定的RelativeSource

如果将AncestorType更改为ContextMenu并绑定到其PlacementTarget,它应该可以工作:

<ContextMenu>
    <MenuItem Header="Remove" Command="{Binding RelativeSource={RelativeSource AncestorType={x:Type ContextMenu}}, 
                    Path=PlacementTarget.DataContext.ValidateAllCommand}">
    </MenuItem>
</ContextMenu>