wpf datagrid,menuitem, style, export ,show in a another window,mvvm
//xaml <Window x:Class="WpfApp58.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" xmlns:behavior="http://schemas.microsoft.com/xaml/behaviors" xmlns:local="clr-namespace:WpfApp58" WindowState="Maximized" mc:Ignorable="d" Title="MainWindow" Height="450" Width="800"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="50"/> <RowDefinition/> <RowDefinition Height="50"/> </Grid.RowDefinitions> <DataGrid x:Name="dg" Grid.Row="1" ItemsSource="{Binding BooksCollection,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" BorderBrush="Blue" BorderThickness="3" SelectionMode="Extended" SelectedItem="{Binding SelectedBook,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" > <behavior:Interaction.Triggers> <behavior:EventTrigger EventName="SelectionChanged" SourceObject="{Binding ElementName=dg}"> <behavior:InvokeCommandAction Command="{Binding SelectionMultiItemsCmd}" CommandParameter="{Binding ElementName=dg,Path=SelectedItems}"/> </behavior:EventTrigger> </behavior:Interaction.Triggers> <DataGrid.Resources> <Style TargetType="MenuItem"> <Setter Property="FontSize" Value="20"/> <Style.Triggers> <Trigger Property="IsMouseOver" Value="True"> <Setter Property="FontSize" Value="30"/> <Setter Property="Foreground" Value="Red"/> <Setter Property="FontWeight" Value="ExtraBold"/> </Trigger> </Style.Triggers> </Style> <Style TargetType="{x:Type DataGridRow}"> <Setter Property="FontSize" Value="20"/> <Setter Property="Foreground" Value="Blue"/> <Style.Triggers> <Trigger Property="IsMouseOver" Value="True"> <Setter Property="FontSize" Value="30"/> <Setter Property="Foreground" Value="Red"/> <Setter Property="Background" Value="Blue"/> </Trigger> <Trigger Property="IsSelected" Value="True"> <Setter Property="FontSize" Value="30"/> </Trigger> </Style.Triggers> </Style> <Style TargetType="{x:Type DataGridCell}"> <Style.Triggers> <Trigger Property="IsMouseOver" Value="True"> <Setter Property="FontSize" Value="40"/> <Setter Property="FontWeight" Value="ExtraBold"/> </Trigger> </Style.Triggers> </Style> </DataGrid.Resources> <DataGrid.ContextMenu> <ContextMenu> <MenuItem Header="Export"> <MenuItem Header="Export Single" Command="{Binding ExportSingleCmd}" /> <MenuItem Header="Export Multiple" Command="{Binding ExportMultiCmd}"/> <MenuItem Header="Export All" Command="{Binding ExportAllCmd}"/> </MenuItem> <MenuItem Header="Show"> <MenuItem Header="Show Single Item" Command="{Binding ShowSingleItemCmd}"/> <MenuItem Header="Show Multi Items" Command="{Binding ShowMultiItemsCmd}"/> <MenuItem Header="Show All Items" Command="{Binding ShowAllItemsCmd}"/> </MenuItem> <MenuItem Header="Serialize"/> </ContextMenu> </DataGrid.ContextMenu> </DataGrid> </Grid> </Window> //xaml.cs using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; 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 WpfApp58 { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); var vm = new MainVM(this); this.DataContext = vm; } } } //mvvm.cs using System; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Web; using System.Windows; using System.Windows.Input; using Microsoft.Win32; using System.Reflection; using Newtonsoft.Json; using System.Runtime.InteropServices.WindowsRuntime; using WpfApp58.Views; using System.Runtime.InteropServices; namespace WpfApp58 { public class MainVM : VMBase { public MainVM(Window winValue) { win = winValue; win.Loaded += Win_Loaded; } #region Events and Methods public DelegateCmd ShowAllItemsCmd => new DelegateCmd(ShowAllItemsCmdExecuted, ShowAllItemsCmdCanExecute); private bool ShowAllItemsCmdCanExecute(object obj) { if (BooksCollection != null && BooksCollection.Any()) { return true; } return false; } private void ShowAllItemsCmdExecuted(object obj) { ShowSelectedItemsInWindow(2); } public DelegateCmd ShowMultiItemsCmd => new DelegateCmd(ShowMultiItemsCmdExecuted, ShowMultiItemsCmdCanExecute); private bool ShowMultiItemsCmdCanExecute(object obj) { if (SelectedMultiBooksCollection != null && selectedMultiBooksCollection.Any()) { return true; } return false; } private void ShowMultiItemsCmdExecuted(object obj) { ShowSelectedItemsInWindow(1); } public DelegateCmd ShowSingleItemCmd => new DelegateCmd(ShowSingleItemCmdExecuted, ShowSingleItemCmdCanExecute); private bool ShowSingleItemCmdCanExecute(object obj) { if (SelectedBook != null) { return true; } return false; } private void ShowSingleItemCmdExecuted(object obj) { ShowSelectedItemsInWindow(0); } private void ShowSelectedItemsInWindow(int idx) { ObservableCollection<Book> showedBooks = new ObservableCollection<Book>(); switch (idx) { case 0: showedBooks.Add(SelectedBook); break; case 1: showedBooks = new ObservableCollection<Book>(SelectedMultiBooksCollection); break; case 2: showedBooks = new ObservableCollection<Book>(BooksCollection); break; } ShowWindow win = new ShowWindow(showedBooks) { Owner = Application.Current.MainWindow }; win.Topmost = true; win.ShowInTaskbar = false; win.ShowDialog(); } public DelegateCmd ExportAllCmd => new DelegateCmd(ExportAllCmdExecuted, ExportAllCmdCanExecute); private bool ExportAllCmdCanExecute(object obj) { if (BooksCollection != null && BooksCollection.Any()) { return true; } return false; } private void ExportAllCmdExecuted(object obj) { if (BooksCollection != null && BooksCollection.Any()) { string fileName = $"AllFile__{DateTime.Now.ToString("yyyyMMddHHmmssffff")}.json"; string allJson = JsonConvert.SerializeObject(BooksCollection, Formatting.Indented); SaveFileToLocal(fileName, allJson); } } public DelegateCmd ExportMultiCmd => new DelegateCmd(ExportMultiCmdExecuted, ExportMultiCmdCanExecute); private bool ExportMultiCmdCanExecute(object obj) { if (SelectedMultiBooksCollection != null && SelectedMultiBooksCollection.Any()) { return true; } return false; } private void ExportMultiCmdExecuted(object obj) { if (SelectedMultiBooksCollection != null && SelectedMultiBooksCollection.Any()) { string fileName = $"SelectedMultiFile__{DateTime.Now.ToString("yyyyMMddHHmmssffff")}.json"; string multiJson = JsonConvert.SerializeObject(SelectedMultiBooksCollection, Formatting.Indented); SaveFileToLocal(fileName, multiJson); } } public DelegateCmd ExportSingleCmd => new DelegateCmd(ExportSingleCmdExecuted, ExportSingleCmdCanExecute); private bool ExportSingleCmdCanExecute(object obj) { if (SelectedBook != null) { return true; } return false; } private void ExportSingleCmdExecuted(object obj) { if (SelectedBook != null) { string fileName = $"SelectedSingleFile__{DateTime.Now.ToString("yyyyMMddHHmmssffff")}.json"; string singleItemJson = JsonConvert.SerializeObject(SelectedBook); SaveFileToLocal(fileName, singleItemJson); } } private void SaveFileToLocal(string fileName, string serializedJson) { SaveFileDialog sfd = new SaveFileDialog(); sfd.FileName = fileName; sfd.InitialDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); if (sfd.ShowDialog() == true) { File.WriteAllText(sfd.FileName, serializedJson); System.Windows.MessageBox.Show($"Save file to {sfd.FileName} successfully", "Export Successfully!", MessageBoxButton.OK, MessageBoxImage.Information); } } public DelegateCmd SelectionMultiItemsCmd => new DelegateCmd(SelectionMultiItemsCmdExecuted); private void SelectionMultiItemsCmdExecuted(object obj) { IList items = obj as IList; if (items != null && items.Count > 0) { int len = items.Count; SelectedMultiBooksCollection = new ObservableCollection<Book>(); for (int i = 0; i < len; i++) { var tempBook = items[i] as Book; if (tempBook != null) { SelectedMultiBooksCollection.Add(tempBook); } } } } private void Win_Loaded(object sender, RoutedEventArgs e) { BooksCollection = new ObservableCollection<Book>(); for (int i = 0; i < 1000000; i++) { BooksCollection.Add(new Book() { Id = i + 1, Title = $"Title__{i + 1}", Name = $"Name__{i + 1}", Description = $"Description__{i + 1}", ISBN = $"ISBN__{i + 1}", Topic = $"Topic__{i + 1}" }); } } #endregion #region Properties private Window win; private ObservableCollection<Book> booksCollection; public ObservableCollection<Book> BooksCollection { get { return booksCollection; } set { if (value != booksCollection) { booksCollection = value; OnPropertyChanged("BooksCollection"); } } } private ObservableCollection<Book> selectedMultiBooksCollection; public ObservableCollection<Book> SelectedMultiBooksCollection { get { return selectedMultiBooksCollection; } set { if (value != selectedMultiBooksCollection) { selectedMultiBooksCollection = value; OnPropertyChanged("SelectedMultiBooksCollection"); } } } private Book selectedBook; public Book SelectedBook { get { return selectedBook; } set { if (value != selectedBook) { selectedBook = value; OnPropertyChanged("SelectedBook"); } } } #endregion } public class DelegateCmd : ICommand { private readonly Action<object> _execute; private readonly Predicate<object> _canExecute; public event EventHandler CanExecuteChanged; public void RaiseCanExecuteChanged() { var handler = CanExecuteChanged; if (handler != null) { handler?.Invoke(this, EventArgs.Empty); } } public DelegateCmd(Action<object> executeValue, Predicate<object> canExecuteValue) { _execute = executeValue; _canExecute = canExecuteValue; } public DelegateCmd(Action<object> executeValue) : this(executeValue, null) { } public bool CanExecute(object parameter) { if (_canExecute == null) { return true; } return _canExecute(parameter); } public void Execute(object parameter) { _execute(parameter); } } public class VMBase : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; public void OnPropertyChanged(string propName) { var handler = PropertyChanged; if (handler != null) { handler?.Invoke(this, new PropertyChangedEventArgs(propName)); } } } public class Book { public int Id { get; set; } public string Name { get; set; } public string Description { get; set; } public string ISBN { get; set; } public string Title { get; set; } public string Topic { get; set; } } } //show window <Window x:Class="WpfApp58.Views.ShowWindow" 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" xmlns:local="clr-namespace:WpfApp58.Views" mc:Ignorable="d" SizeToContent="WidthAndHeight" Title="ShowWindow" Height="450" Width="800"> <Grid> <DataGrid x:Name="dg" /> </Grid> </Window> //showwindow.xaml.cs using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Text; using System.Threading.Tasks; 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.Shapes; namespace WpfApp58.Views { /// <summary> /// Interaction logic for ShowWindow.xaml /// </summary> public partial class ShowWindow : Window { public ShowWindow(ObservableCollection<Book> books) { InitializeComponent(); dg.ItemsSource= books; } } }