WPF Datagrid mvvm contextmenu menuitem command commandparameter binding to selecteditems

<MenuItem Header="Remove Book" Command="{Binding RemoveBookCommand}"
          CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor,
          AncestorType={x:Type ContextMenu}},Path=PlacementTarget.SelectedItems}"/>

 

//all
//xaml
<Window x:Class="WpfApp34.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        WindowState="Maximized"
        xmlns:local="clr-namespace:WpfApp34"
        mc:Ignorable="d"
        Title="{Binding BooksCollectionCount,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
        Height="450" Width="800">
    <Grid>
        <DataGrid ItemsSource="{Binding BooksCollection,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
                  IsReadOnly="True"
                  SelectionMode="Extended"
                  AutoGenerateColumns="False"
                  VirtualizingPanel.IsVirtualizing="True"
                  VirtualizingPanel.CacheLength="1"
                  VirtualizingPanel.CacheLengthUnit="Item">
            <DataGrid.RowStyle>
                <Style TargetType="{x:Type DataGridRow}">
                    <Setter Property="Height" Value="500"/>
                    <Setter Property="FontSize" Value="30"/>
                    <Style.Triggers>
                        <Trigger Property="IsMouseOver" Value="True">
                            <Setter Property="Height" Value="1000"/>
                            <Setter Property="FontSize" Value="50"/>
                        </Trigger>
                    </Style.Triggers>
                </Style>
            </DataGrid.RowStyle>
            <DataGrid.Columns>
                <DataGridTemplateColumn>
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <Border>
                                <Border.Background>
                                    <ImageBrush ImageSource="{Binding DataContext.ImgSource,
                                        RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type DataGridRow}}}"
                                                Stretch="Uniform"/>
                                </Border.Background>
                                <Grid>
                                    <Grid.RowDefinitions>
                                        <RowDefinition/>
                                        <RowDefinition/>
                                    </Grid.RowDefinitions>
                                    <Grid.ColumnDefinitions>
                                        <ColumnDefinition/>
                                        <ColumnDefinition/>
                                        <ColumnDefinition/>
                                    </Grid.ColumnDefinitions>
                                    <TextBlock Text="{Binding Id}" Grid.Row="0" Grid.Column="0"/>
                                    <TextBlock Text="{Binding Name}" Grid.Row="0" Grid.Column="1"/>
                                    <TextBlock Text="{Binding Title}" Grid.Row="0" Grid.Column="2"/>
                                    <TextBlock Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" 
                                               Text="{Binding ISBN}"/>
                                </Grid>
                            </Border>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
            </DataGrid.Columns>
            <DataGrid.ContextMenu>
                <ContextMenu>
                    <MenuItem Header="Add Book" Command="{Binding AddBookCommand}"/>
                    <MenuItem Header="Remove Book" Command="{Binding RemoveBookCommand}"
                              CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor,
                              AncestorType={x:Type ContextMenu}},Path=PlacementTarget.SelectedItems}"/>
                    <MenuItem Header="Edit Book" Command="{Binding EditBookCommand}"
                              CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor,
                              AncestorType={x:Type ContextMenu}},Path=PlacementTarget.SelectedItems}"/>
                </ContextMenu>
            </DataGrid.ContextMenu>
        </DataGrid>
    </Grid>
</Window>



//cs
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.Runtime.CompilerServices;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfApp34
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            var vm = new MainVM();
            this.DataContext = vm;
        }
    }

    public class MainVM : NotifyBase
    {
        //EditWindow editWin { get; set; }
        public MainVM()
        {
            InitBooks();
            InitCommands();
        }

        private void InitCommands()
        {
            AddBookCommand = new DelCommand(AddBookCommandExecuted);
            RemoveBookCommand = new DelCommand(RemoveBookCommandExecuted);
            EditBookCommand = new DelCommand(EditBookCommandExecuted);
            ConfirmCommand = new DelCommand(ConfirmCommandExecuted);
            CancelCommand = new DelCommand(CancelCommandExecuted);
            TextChangedCommand = new DelCommand(TextChangedCommandExecuted);
        }

        private void TextChangedCommandExecuted(object? obj)
        {
            
        }

        private void AddBookCommandExecuted(object? obj)
        {

        }

        private void RemoveBookCommandExecuted(object? obj)
        {
            var items = (obj as System.Collections.IList).Cast<Book>()?.ToList();
            if (items == null && !items.Any())
            {
                return;
            }
            var msgBox = MessageBox.Show("Delete Selected Items?",
                "Delete",
                MessageBoxButton.YesNo, MessageBoxImage.Question, MessageBoxResult.Yes);
            if (msgBox == MessageBoxResult.Yes)
            {
                foreach (var item in items)
                {
                    BooksCollection.Remove(item);
                }
            }
        }

        private void EditBookCommandExecuted(object? obj)
        {
            //var items = (obj as System.Collections.IList).Cast<Book>()?.ToList();
            //if (items == null && !items.Any())
            //{
            //    return;
            //}
            //editWin = new EditWindow();
            //editWin.DataContext = this;
            //SelectedBooks = new ObservableCollection<Book>(items);
            
           
            //if (editWin.ShowDialog() == true)
            //{
               
                
            //}
        }
        private void ConfirmCommandExecuted(object? obj)
        {
            //editWin.DialogResult = true;
        }

        private void CancelCommandExecuted(object? obj)
        {
            //editWin.DialogResult = false;
        }


        public DelCommand AddBookCommand { get; set; }
        public DelCommand RemoveBookCommand { get; set; }
        public DelCommand EditBookCommand { get; set; }
        public DelCommand ConfirmCommand { get; set; }
        public DelCommand CancelCommand { get; set; }
        public DelCommand TextChangedCommand { get; set; }

        int index = 0;
        private void InitBooks()
        {
            var dir = @"../../../Images";
            if (Directory.Exists(dir))
            {
                var imgs = Directory.GetFiles(dir);
                int imgsCount = imgs.Count();
                BooksCollection = new ObservableCollection<Book>();
                SelectedBooks = new ObservableCollection<Book>();
                BooksCollection.CollectionChanged += BooksCollection_CollectionChanged;
                for (int i = 0; i < 10000; i++)
                {
                    var bk = new Book()
                    {
                        Id = ++index,
                        Name = $"Name_{index}",
                        Title = $"Title_ {index}",
                        ISBN = $"ISBN-{Guid.NewGuid().ToString("N")}",
                        ImgSource = new BitmapImage(new Uri(imgs[i % imgsCount], UriKind.RelativeOrAbsolute))
                    };
                    BooksCollection.Add(bk);
                }
            }
        }

        private void BooksCollection_CollectionChanged(object? sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
        {
            BooksCollectionCount = BooksCollection.Count;
        }

        

        private int booksCollectionCount;
        public int BooksCollectionCount
        {
            get
            {
                return booksCollectionCount;
            }
            set
            {
                if (value != booksCollectionCount)
                {
                    booksCollectionCount = value;
                    OnPropertyChanged();
                }
            }
        }

        private ObservableCollection<Book> booksCollection;
        public ObservableCollection<Book> BooksCollection
        {
            get
            {
                return booksCollection;
            }
            set
            {
                if (value != booksCollection)
                {
                    booksCollection = value;
                    OnPropertyChanged();
                    BooksCollectionCount = BooksCollection.Count;
                }
            }
        }

        private ObservableCollection<Book> selectdBooks;
        public ObservableCollection<Book> SelectedBooks
        {
            get
            {
                return selectdBooks;
            }
            set
            {
                if (value != selectdBooks)
                {
                    selectdBooks = value;
                    OnPropertyChanged();
                }
            }
        }
    }

    public class Book: NotifyBase
    {
        public int Id { get; set; }
        private string name;
        public string Name
        {
            get
            {
                return name;
            }
            set
            {
                if (value!=name)
                {
                    name = value;
                    OnPropertyChanged(nameof(Name));
                }
            }
        }

        private string title;
        public string Title
        {
            get
            {
                return title;
            }
            set
            {
                if(value != title)
                {
                    title = value;
                    OnPropertyChanged();
                }
            }
        }

        private string iSBN;
        public string ISBN
        {
            get
            {
                return iSBN;
            }
            set
            {
                if (value != iSBN)
                {
                    iSBN = value;
                    OnPropertyChanged();
                }
            }
        }
        public ImageSource ImgSource { get; set; }
    }


    public class DelCommand : ICommand
    {
        private Action<object?> execute;
        private Predicate<object?> canExecute;
        private DelCommand textChangedCommand;

        public DelCommand(DelCommand textChangedCommand)
        {
            this.textChangedCommand = textChangedCommand;
        }

        public DelCommand(Action<object?> executeValue, Predicate<object?> canExecuteValue = null)
        {
            execute = executeValue;
            canExecute = canExecuteValue;
        }

        public event EventHandler? CanExecuteChanged
        {
            add
            {
                CommandManager.RequerySuggested += value;
            }
            remove
            {
                CommandManager.RequerySuggested -= value;
            }
        }


        public bool CanExecute(object? parameter)
        {
            return canExecute == null ? true : canExecute(parameter);
        }

        public void Execute(object? parameter)
        {
            execute(parameter);
        }
    }

    public class NotifyBase: INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler? PropertyChanged;
        public void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

 

 

 

 

 

 

posted @ 2025-06-07 21:55  FredGrit  阅读(17)  评论(0)    收藏  举报