【问题标题】:Bind ListViewItem ContextMenu MenuItem Command to ViewModel of the ListView's ItemsSource将 ListViewItem ContextMenu MenuItem 命令绑定到 ListView 的 ItemsSource 的 ViewModel
【发布时间】:2020-07-12 10:51:35
【问题描述】:

我有一个 ListViewExpanders。每个Expander(代表一个数据库表)下都有项目,在另一个ListView 中。我想右键单击并在最里面的项目上有一个“编辑”选项,这些项目代表相应数据库表中的记录。

在我的MainEditorViewModel 中有一个名为“编辑”的ICommand。该命令所在的Datacontext与最外层的ListView名为“TestGroupsListView”的Datacontext相同

这是扩展器 ListView 的 XAML 标记。我为通过ElementNameMenuItemBinding 绑定引用而命名的最外层ListView:

        <ListView Name="TestGroupsListView" ItemsSource="{Binding TestGroups}" Grid.Row="1">
            <ListView.ItemTemplate>
                <DataTemplate>


                    <Expander Style="{StaticResource MaterialDesignExpander}"  >
                        <Expander.Header>
                            <Grid MaxHeight="50">
                                <TextBlock Text="{Binding Name}"/>
                                <Grid.ContextMenu>

                                    <ContextMenu>
                                        <MenuItem Header="Add..." Command="{Binding Add}"/>
                                    </ContextMenu>
                                </Grid.ContextMenu>
                            </Grid>

                        </Expander.Header>

                        <ListView ItemsSource="{Binding Records}" Style="{StaticResource MaterialDesignListView}" Margin="30 0 0 0">
                            <ListView.ItemTemplate>
                                <DataTemplate>
                                    <Grid>
                                        <Grid.ContextMenu>
                                            <ContextMenu>
                                                <MenuItem Header="Edit" 
                                                          Command="{Binding ElementName=TestGroupsListView, Path=DataContext.Edit}"
                                                          CommandParameter="{Binding }"/>
                                            </ContextMenu>
                                        </Grid.ContextMenu>

                                        <Button Content="{Binding RecordName}" Command="{Binding ElementName=TestGroupsListView, Path=DataContext.Edit}"/>
                                        <!--<TextBlock Text="{Binding RecordName}" AllowDrop="True"/>-->
                                    </Grid>
                                </DataTemplate>
                            </ListView.ItemTemplate>
                        </ListView>
                    </Expander>
                </DataTemplate>
            </ListView.ItemTemplate>

        </ListView>

我能够成功地将 DataTemplate 中的按钮绑定到“编辑”,但是当我尝试将 MenuItemCommand 绑定到“编辑”时,什么也没有发生。为什么这可能是按钮命令绑定使用 ElementName 工作,但 ContextMenu 中的相同绑定不工作?

【问题讨论】:

    标签: wpf listview mvvm data-binding binding


    【解决方案1】:

    我认为最好对 ListView 全局使用上下文菜单,对每个子 ListView 全局使用上下文菜单。好的,这是我的解决方案:

    <ListBox ItemsSource="{Binding Groups}">
        <ListBox.ContextMenu>
            <ContextMenu>
                <MenuItem Header="Add..." Command="{Binding Add}"/>
            </ContextMenu>
        </ListBox.ContextMenu>
        <ListBox.ItemTemplate>
            <DataTemplate>
                <Expander Header="{Binding Name}">
                    <ListView ItemsSource="{Binding Records}" SelectedItem="{Binding SelectedRecord}">
                        <ListView.ContextMenu>
                            <ContextMenu>
                                <MenuItem Header="Edit" Command="{Binding Edit}" IsEnabled="{Binding CanEdit}"/>
                            </ContextMenu>
                        </ListView.ContextMenu>
                        <ListView.ItemTemplate>
                            <DataTemplate>
                                <TextBlock Text="{Binding Name}"/>
                            </DataTemplate>
                        </ListView.ItemTemplate>
                    </ListView>
                </Expander>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
    

    为了更好地理解背后的代码:

    public class GroupsVM : ViewModelBase
    {
        public ICommand Add
        {
            get => null; //Command implementation
        }
    
        public ObservableCollection<GroupVM> Groups { get; set; } = new ObservableCollection<GroupVM>()
        {
            new GroupVM { Name = "First" },
            new GroupVM { Name = "Second" },
            new GroupVM { Name = "Third" }
        };
    }
    
    public class GroupVM : ViewModelBase
    {
        private string _name;
    
        public string Name
        {
            get => _name;
            set { _name = value; OnPropertyChanged(); }
        }
    
        public ICommand Edit
        {
            get => null; //Command implementation
        }
    
        public bool CanEdit => SelectedRecord != null;
    
        public ObservableCollection<RecordVM> Records { get; set; } = new ObservableCollection<RecordVM>()
        {
            new RecordVM { Name="Record1" },
            new RecordVM { Name="Record2" },
            new RecordVM { Name="Record3" }
        };
    
        private RecordVM _selectedRecord = null;
    
        public RecordVM SelectedRecord
        {
            get => _selectedRecord;
            set
            {
                _selectedRecord = value;
                OnPropertyChanged();
                OnPropertyChanged("CanEdit");
            }
        }
    }
    
    public class RecordVM : ViewModelBase
    {
        private string _name;
    
        public string Name
        {
            get => _name;
            set { _name = value; OnPropertyChanged(); }
        }
    }
    

    【讨论】:

    • 谢谢!我喜欢那里的每一位都有一个单独的视图模型,一个用于 TestGroup 和一个用于记录。我几乎拥有它,但这种方式对我来说很有意义。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-11-04
    • 1970-01-01
    • 2011-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多