【问题标题】:Execute the Command in Listview MenuItem MVVM执行 Listview MenuItem MVVM 中的命令
【发布时间】:2019-05-02 01:30:44
【问题描述】:

为什么我的 Listview 菜单项中的命令没有执行?

这是我的 Listview 上的代码

<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被执行了。

而 MenuItem 中的 Command 不是。

我的绑定有什么问题?

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

谢谢。

【问题讨论】:

    标签: c# wpf listview mvvm menuitem


    【解决方案1】:

    我有时也会在ContextMenu 中使用MenuItems 时遇到这个问题。我猜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();
        }
    }
    

    在您的视图资源(用户控件或窗口)中,您必须添加代理,例如:

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

    在您的 MenuItem 中,您可以使用它:

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

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

        【解决方案3】:

        为什么我的 Listview 菜单项中的命令没有执行?

        因为ListView 不是MenuItem 的视觉祖先,所以找不到绑定的RelativeSource

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-02-26
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-07-12
          • 1970-01-01
          相关资源
          最近更新 更多