Обновление свойства члена коллекции в другой коллекции для отображения в DataGrid - PullRequest
0 голосов
/ 15 сентября 2018

Как сделать так, чтобы при изменении свойства члена коллекции в коллекции оно обновлялось на экране сетки данных?

В моем примере у меня есть ObservableCollection of Employees.Каждый сотрудник имеет свойство List.Когда я назначу значение «Автомобиль сотрудника» новому списку, он будет успешно обновлен.Когда я назначаю свойство Model автомобиля сотрудника, оно не обновляется.

MainWindow.xaml

<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Class="DataBindings.MainWindow" Title="MainWindow" Height="332" Width="474" DataContext="{Binding RelativeSource={RelativeSource Self}}">
<Window.Resources>
    <CollectionViewSource x:Key="GridDataSource" Source="{Binding Employees}" />
</Window.Resources>
<Grid Margin="0,0,0,-1">
    <Grid.RowDefinitions>
        <RowDefinition Height="auto" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>
    <DataGrid Grid.Row="1" ItemsSource="{Binding Source={StaticResource GridDataSource}}" AutoGenerateColumns="False" CanUserAddRows="False" Margin="0,0,0,114">
        <DataGrid.Columns>
            <DataGridTextColumn x:Name="Names" Width="Auto" Header="Name" Binding="{Binding Name}" />
            <DataGridTextColumn x:Name="Cars" Width="Auto" Header="Cars" Binding="{Binding CarsString}" />
        </DataGrid.Columns>
    </DataGrid>
    <Button Content="Update" Click="Update" HorizontalAlignment="Left" Margin="170,202,0,-20" Grid.Row="1" VerticalAlignment="Top" Width="75" />
</Grid>

MainWindow.xaml.cs

using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Windows;

namespace DataBindings
{
    public partial class MainWindow : Window
    {
        DAL dataAccess = new DAL();

        public MainWindow()
        {
            InitializeComponent();

        }

        public ObservableCollection<Employee> Employees { get { return dataAccess.EmployeesList; } }

        private void Update(object sender, RoutedEventArgs e)
        {
            Employees[1].Name = "Mike"; //changing the name property on the collection of employees works
            Debug.WriteLine($"Mike's Car is a {Employees[1].Cars[0].Model}");
            Employees[1].Cars[0].Model = "Volvo"; //changing the model of car in a cars list does not
            Debug.WriteLine($"Mike's Car is a {Employees[1].Cars[0].Model}");
        }

    }
}

DAL.cs

using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;

namespace DataBindings
{
    public class DAL : ObservableCollection<Employee>
    {
        public ObservableCollection<Employee> EmployeesList = new ObservableCollection<Employee>();
        public DAL()
        {
            List<Car> carList = new List<Car>();
            carList.Add(new Car { Model = "Ford" });
            carList.Add(new Car { Model = "Honda" });
            EmployeesList.Add(new Employee { Name = "Bob", Cars = carList });
            EmployeesList.Add(new Employee { Name = "John", Cars = carList });
            //EmployeesList.CollectionChanged += EmployeesList_CollectionChanged;
        }

    }

    public class Employee : INotifyPropertyChanged
    {
        private string empName;
        public List<Car> empCars = new List<Car>();
        private string carsString;

        public string Name
        {
            get { return this.empName; }
            set
            {
                if (this.empName != value)
                {
                    empName = value;
                    this.NotifyPropertyChanged("Name");
                };
            }
        }
        public List<Car> Cars
        {
            get { return this.empCars; }
            set
            {
                if (this.empCars != value)
                {
                    empCars = value;
                    carsToString(empCars);
                    this.NotifyPropertyChanged("Cars");
                };
            }
        }
        public string CarsString
        {
            get { return this.carsString; }
            set
            {
                if (this.carsString != value)
                {
                    carsString = value;
                    this.NotifyPropertyChanged("CarsString");
                };
            }
        }


        public void carsToString(List<Car> Cars)
        {
            string carString = "";
            foreach (Car car in Cars)
            {
                carString += car.Model + " ";
            }
            CarsString = carString;
        }

        public event PropertyChangedEventHandler PropertyChanged;

        public void NotifyPropertyChanged(string propName)
        {
            if (this.PropertyChanged != null)
                this.PropertyChanged(this, new PropertyChangedEventArgs(propName));
        }

    }
    public class Car : INotifyPropertyChanged
    {
        private string carModel;

        public string Model
        {
            get { return this.carModel; }
            set
            {
                if (this.carModel != value)
                {
                    carModel = value;
                    this.NotifyPropertyChanged("Model");
                };
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        public void NotifyPropertyChanged(string propName)
        {
            if (this.PropertyChanged != null)
                this.PropertyChanged(this, new PropertyChangedEventArgs(propName));
        }

    }
}

1 Ответ

0 голосов
/ 15 сентября 2018

Я немного изменил ваш код, и IMO можно улучшить еще больше.

Вот мой xaml:

<Window.DataContext>
        <local:DAL />
    </Window.DataContext>
    <Grid Margin="0,0,0,-1">
        <Grid.RowDefinitions>
            <RowDefinition Height="auto" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>
        <DataGrid x:Name="grid" Grid.Row="1" ItemsSource="{Binding EmployeesList}" AutoGenerateColumns="False" CanUserAddRows="False" Margin="0,0,0,114">
            <DataGrid.Columns>
                <DataGridTemplateColumn Header="Names">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding Name}" />
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
                <DataGridTemplateColumn Header="Cars">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding CarsString, Mode=TwoWay}" />
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
            </DataGrid.Columns>
        </DataGrid>
        <Button Content="Update" Click="Update" HorizontalAlignment="Left" Margin="170,202,0,-20" Grid.Row="1" VerticalAlignment="Top" Width="75" />
    </Grid>

Вот мой код: вы можете иметь ICommand для вашегоUpdateButton, чтобы вы могли оставить свой код чистым: https://www.c -sharpcorner.com / UploadFile / e06010 / wpf-icommand-in-mvvm /

public DAL VM => (DAL) DataContext; 
        public MainWindow()
        {
            InitializeComponent();
        }

        private void Update(object sender, RoutedEventArgs e)
        {
            VM.EmployeesList[1].Name = "Mike"; //changing the name property on the collection of employees works
            Debug.WriteLine($"Mike's Car is a {VM.EmployeesList[1].Cars[0].Model}");
            VM.EmployeesList[1].Cars[0].Model = "Volvo"; //changing the model of car in a cars list does not
            Debug.WriteLine($"Mike's Car is a {VM.EmployeesList[1].Cars[0].Model}");
        }

Вот мои DAL.csОбратите внимание, что я изменил ваш список на ObservableCollection, а затем в средствах доступа необходимо убедиться, что CarsString обновлен, поскольку вы не обновляете его непосредственно в своем представлении.

 public class DAL : INotifyPropertyChanged
    {
        private ObservableCollection<Employee> _employeesList;
        public ObservableCollection<Employee> EmployeesList
        {
            get => _employeesList;
            set
            {
                _employeesList = value;
                OnPropertyChanged();
            }
        }
        public DAL()
        {
            EmployeesList = new ObservableCollection<Employee>();
            ObservableCollection<Car> carList = new ObservableCollection<Car>();
            carList.Add(new Car { Model = "Ford" });
            carList.Add(new Car { Model = "Honda" });
            EmployeesList.Add(new Employee { Name = "Bob", Cars = carList });
            EmployeesList.Add(new Employee { Name = "John", Cars = carList });
            //EmployeesList.CollectionChanged += EmployeesList_CollectionChanged;
        }

        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    public class Employee : INotifyPropertyChanged
    {
        private string empName;
        public ObservableCollection<Car> empCars = new ObservableCollection<Car>();
        private string carsString;

        public string Name
        {
            get { return this.empName; }
            set
            {
                if (this.empName != value)
                {
                    empName = value;
                    this.NotifyPropertyChanged("Name");
                };
            }
        }
        public ObservableCollection<Car> Cars
        {
            get
            {
                carsToString(empCars);
                this.NotifyPropertyChanged("CarsString");
                return this.empCars;

            }
            set
            {
                if (this.empCars != value)
                {
                    empCars = value;
                    carsToString(empCars);
                    this.NotifyPropertyChanged("Cars");
                    this.NotifyPropertyChanged("CarsString");
                };
            }
        }
        public string CarsString
        {
            get { return this.carsString; }
            set
            {
                if (this.carsString != value)
                {
                    carsString = value;
                    this.NotifyPropertyChanged("CarsString");
                };
            }
        }


        public void carsToString(ObservableCollection<Car> Cars)
        {
            string carString = "";
            foreach (Car car in Cars)
            {
                carString += car.Model + " ";
            }
            CarsString = carString;
        }

        public event PropertyChangedEventHandler PropertyChanged;

        public void NotifyPropertyChanged(string propName)
        {
            if (this.PropertyChanged != null)
                this.PropertyChanged(this, new PropertyChangedEventArgs(propName));
        }

    }
    public class Car : INotifyPropertyChanged
    {
        private string carModel;

        public string Model
        {
            get { return this.carModel; }
            set
            {
                if (this.carModel != value)
                {
                    carModel = value;
                    this.NotifyPropertyChanged("Model");
                };
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        public void NotifyPropertyChanged(string propName)
        {
            if (this.PropertyChanged != null)
                this.PropertyChanged(this, new PropertyChangedEventArgs(propName));
        }
    }

enter image description here

enter image description here

...