WPF mainwindow show data and edit window edit data, share the same viewmodel

//main.xaml
<Window x:Class="WpfApp235.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:local="clr-namespace:WpfApp235"
        mc:Ignorable="d"
        WindowState="Maximized"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <DataGrid x:Name="dg"
                  AutoGenerateColumns="False"
                  ItemsSource="{Binding BooksList,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
                  SelectionMode="Extended"
                  IsReadOnly="True"
                  Width="{Binding DgWidth,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}">
            <DataGrid.RowStyle>
                <Style TargetType="{x:Type DataGridRow}">
                    <Setter Property="Height" Value="100"/>
                    <Setter Property="FontSize" Value="30"/>
                </Style>
            </DataGrid.RowStyle>
            <DataGrid.ContextMenu>
                <ContextMenu>
                    <ContextMenu.Items>
                        <MenuItem Header="Edit"
                                  Command="{Binding SelectedMultipleCommand}"
                                  CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type ContextMenu}},Path=PlacementTarget.SelectedItems}"/>
                            
                    </ContextMenu.Items>
                </ContextMenu>
            </DataGrid.ContextMenu>
            <DataGrid.Columns>
                <DataGridTextColumn Binding="{Binding Id}"/>
                <DataGridTextColumn Binding="{Binding Name}"/>
                <DataGridTextColumn Binding="{Binding Title}"/>
                <DataGridTextColumn Binding="{Binding ISBN}"/>
                <DataGridTextColumn Binding="{Binding Summary}"/>
            </DataGrid.Columns>
        </DataGrid>
                   
    </Grid>
</Window>


//main.xaml.cs
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
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 WpfApp235
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            var vm = new MainVM(this);
            this.DataContext = vm;
        }
    }

    public class MainVM : INotifyPropertyChanged
    {
        Window mainWin;
        FrameworkElement fe;
        public MainVM(Window winValue)
        {
            mainWin = winValue;
            if(mainWin != null)
            {
                mainWin.Loaded += MainWin_Loaded;
                mainWin.SizeChanged += MainWin_SizeChanged;
            }
           
        }

        private void MainWin_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            Init();
        }

        private void MainWin_Loaded(object sender, RoutedEventArgs e)
        {
            Init();
        }

        private void Init()
        {
            var tempFe=mainWin.Content as FrameworkElement;
            if(tempFe != null)
            {
                fe= tempFe;
                DgWidth = fe.ActualWidth;
            }
            InitBooksList();
            InitCommands();
            
        }

        public DelCommand SelectedMultipleCommand { get; set; }

        public DelCommand SaveCommand { get; set; }

        public DelCommand CancelCommad { get; set; }
        private void InitCommands()
        {
            SelectedMultipleCommand = new DelCommand(SelectedMultipleCommandExecuted);
            SaveCommand = new DelCommand(SaveCommandExecuted);
            CancelCommad = new DelCommand(CancelCommadExecuted);
        }

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

        private void SaveCommandExecuted(object? obj)
        {
            editWin.DialogResult = true;
        }

        EditWin editWin { get; set; }
        private void SelectedMultipleCommandExecuted(object? obj)
        {
            var items = ((System.Collections.IList)obj).Cast<Book>()?.ToList();
            SelectedBooks = new ObservableCollection<Book>(items);
            SubBooksList = new ObservableCollection<Book>();
            for(int i=0;i<items.Count;i++)
            {
                SubBooksList.Add(new Book()
                {
                    Id = items[i].Id,
                    Title = items[i].Title,
                    Name = items[i].Name,
                    ISBN = items[i].ISBN,
                    Summary = items[i].Summary
                });
            }
            editWin = new EditWin();
            editWin.DataContext = this;
            if (editWin.ShowDialog() == true)
            {
                var diffParts=SubBooksList.Where(x=>!SelectedBooks.Any(y=>x.Id==y.Id
                && x.Name==y.Name && x.ISBN==y.ISBN && x.Summary==y.Summary && x.Title==y.Title));  
                foreach(Book book in diffParts)
                {
                    var bk = BooksList.Where(x => x.Id == book.Id).FirstOrDefault();
                    int idx=BooksList.IndexOf(bk);
                    if(idx>=0)
                    {
                        BooksList[idx] = new Book()
                        {
                            Id=book.Id,
                            Name=book.Name,
                            ISBN=book.ISBN,
                            Summary=book.Summary,
                            Title=book.Title
                        };
                    }
                }     
            }         
        }

        private void InitBooksList()
        {
            BooksList = new ObservableCollection<Book>();
            for (int i = 0; i < 1000; i++)
            {
                BooksList.Add(new Book()
                {
                    Id = i + 1,
                    Name = $"Name_{i + 1}",
                    Title = $"Title_{i + 1}",
                    ISBN = $"ISBN_{i + 1}",
                    Summary = $"Summary_{i + 1}"
                });
            }
        }

        public event PropertyChangedEventHandler? PropertyChanged;
        private void OnPropertyChanged([CallerMemberName] string propertyName = "")
        {
            var handler = PropertyChanged;
            if (handler != null)
            {
                handler?.Invoke(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        private double dgWidth;
        public double DgWidth
        {
            get
            {
                return dgWidth;
            }
            set
            {
                if (dgWidth != value)
                {
                    dgWidth = value;
                    OnPropertyChanged();
                }
            }
        }

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

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

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

    public class Book
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Title { get; set; }
        public string ISBN { get; set; }
        public string Summary { get; set; }

        //public Object Clone()
        //{
        //    Book newBook = new Book();
        //    newBook.Id = Id;
        //    newBook.Name = Name;
        //    newBook.Title = Title;
        //    newBook.ISBN = ISBN;
        //    newBook.Summary = Summary;
        //    return newBook;
        //}

        //public Book DeepClone()
        //{
        //    return (Book)this.Clone();
        //}

        //public bool Equals(Book? other)
        //{
        //     if(other is null)
        //    {
        //        return false;
        //    } 
        //     return Id==other.Id
        //        && string.Equals(Name, other.Name) 
        //        && string.Equals(Title, other.Title)
        //        && string.Equals(ISBN, other.ISBN)
        //        && string.Equals(Summary, other.Summary);
        //}
    }

    public class DelCommand : ICommand
    {
        private Action<object?> execute;
        private Predicate<object?> canExecute;
        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);
        }
    }
}


//EditWin.xaml
<Window x:Class="WpfApp235.EditWin"
        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:WpfApp235"
        mc:Ignorable="d"
        Title="EditWin" 
        Height="600" Width="1200">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition Height="100"/>
        </Grid.RowDefinitions>
        <DataGrid x:Name="dg"
          AutoGenerateColumns="False"
          ItemsSource="{Binding SubBooksList,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
          SelectionMode="Extended">
            <DataGrid.RowStyle>
                <Style TargetType="{x:Type DataGridRow}">
                    <Setter Property="Height" Value="50"/>
                    <Setter Property="FontSize" Value="30"/>
                </Style>
            </DataGrid.RowStyle>
            <DataGrid.Columns>
                <DataGridTextColumn Binding="{Binding Id}" IsReadOnly="True"/>
                <DataGridTextColumn Binding="{Binding Name}"/>
                <DataGridTextColumn Binding="{Binding Title}"/>
                <DataGridTextColumn Binding="{Binding ISBN}"/>
                <DataGridTextColumn Binding="{Binding Summary}"/>
            </DataGrid.Columns>
        </DataGrid>
        <StackPanel Grid.Row="1" Orientation="Horizontal">
            <Button Command="{Binding SaveCommand}" Width="200"
                    Content="Save"/>
            <Button Command="{Binding CancelCommad}" Width="200"
                    Content="Cancel"/>
        </StackPanel>
    </Grid>
</Window>

 

 

 

 

 

 

\

 

 

 

 

 

 

 

 

posted @ 2025-05-28 00:58  FredGrit  阅读(6)  评论(0)    收藏  举报