<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));
}
}
}
![]()
![]()