如何在更改 属性 时更新 DataGrid ItemsSource?

How to Update DataGrid ItemsSource when change its Property?

这是示例代码:

public class GridViewWindowViewModel : INotifyPropertyChanged
    {
        public GridViewWindowViewModel()
        {
            Tables = new ObservableCollection<string> { "Person", "Car" };
            SainaAccessEntity = new SainaAccessEntity { TableName = "Person" };
        }

        private SainaAccessEntity _SainaAccessEntity;

        public SainaAccessEntity SainaAccessEntity
        {
            get { return _SainaAccessEntity; }
            set
            {
                if (_SainaAccessEntity != value)
                {
                    _SainaAccessEntity = value;
                    OnPropertyChanged();
                }
            }
        }

        private ObservableCollection<string> _Tables;

        public ObservableCollection<string> Tables
        {
            get { return _Tables; }
            set
            {
                if (_Tables != value)
                {
                    _Tables = value;
                    OnPropertyChanged();
                }
            }
        }

        public event PropertyChangedEventHandler PropertyChanged = delegate { };
        private void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }

    }

这是模特 Class :

public class SainaAccessEntity : INotifyPropertyChanged
    {
        private string _TableName;

        public string TableName
        {
            get { return _TableName; }
            set
            {
                if (value != _TableName)
                {
                    _TableName = value;
                    OnPropertyChanged();
                }
            }
        }

        public event PropertyChangedEventHandler PropertyChanged = delegate { };
        private void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

自定义数据网格视图:

public class MyDataGrid : DataGrid
{
    public MyDataGrid()
    {
        var x = new ObservableCollection<Person> { new Person { Name = "Ali", Family = "Jalilvand" } };
    }
    public SainaAccessEntity SainaAccessEntity
    {
        get { return (SainaAccessEntity)GetValue(SainaAccessEntityProperty); }
        set { SetValue(SainaAccessEntityProperty, value); }
    }
    public static readonly DependencyProperty SainaAccessEntityProperty =
        DependencyProperty.Register("SainaAccessEntity", typeof(SainaAccessEntity), typeof(MyDataGrid), new PropertyMetadata(null, SainaAccessEntity_Changed));

    private static void SainaAccessEntity_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var u = d as MyDataGrid;
        if (u.SainaAccessEntity.TableName == "Person")
        {
            u.ItemsSource = new ObservableCollection<Person> { new Person { Name = "Ali", Family = "Bayat" } };
        }
        else
        {
            u.ItemsSource = new ObservableCollection<Car1> { new Car1 { Name = "BMW", Model = "518",Color="Red" } };
        }

    }

}

汽车和人模型:

public class Car1
{
    public string Model { get; set; }
    public string Name { get; set; }
    public string Color { get; set; }

}

public class Person
{
    public string Name { get; set; }
    public string Family { get; set; }
}

主要WindowXAML:

<Window x:Class="TestWpfApplication.GridViewWindow"
        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:TestWpfApplication"
        mc:Ignorable="d"
        Title="GridViewWindow" Height="300" Width="300">
    <Window.Resources>
        <local:GridViewWindowViewModel x:Key="Vm"/>
    </Window.Resources>
    <Grid DataContext="{StaticResource Vm}">
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="auto"/>
        </Grid.RowDefinitions>
        <local:MyDataGrid  VerticalAlignment="Top" SainaAccessEntity="{Binding SainaAccessEntity, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
        <ComboBox Margin="0,5.694,0,0" Grid.Row="1" ItemsSource="{Binding Tables, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" SelectedItem="{Binding SainaAccessEntity.TableName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"></ComboBox>
    </Grid>
</Window>

如何在更改其 属性 时更新 DataGrid ItemsSource? 我在 WPF 中有自定义数据网格,它有一个定义 table 名称的 属性,我想动态更改 ItamsSource,当更改此 属性...

这里你的 属性 'SainaAccessEntity' 没有改变,只有 TableName 在改变。为此,您可以尝试下面的代码,或者您可以将类型从 'SainaAccessEntity' 更改为字符串。

更改'SainaAccessEntity_Changed'方法的代码

        var u = d as MyDataGrid;

        if (u.SainaAccessEntity == null)
        {
            return;
        }

        // intial set value
        if (u.SainaAccessEntity.TableName == "Person")
        {
            u.ItemsSource = new ObservableCollection<Person> { new Person { Name = "Ali", Family = "Bayat" } };
        }
        else
        {
            u.ItemsSource = new ObservableCollection<Car1> { new Car1 { Name = "BMW", Model = "518", Color = "Red" } };
        }

        // set value on change
        var _notify = u.SainaAccessEntity as INotifyPropertyChanged;
        if (_notify != null)
        {
            _notify.PropertyChanged += (sender, ev) =>
            {
                if (u.SainaAccessEntity.TableName == "Person")
                {
                    u.ItemsSource = new ObservableCollection<Person> { new Person { Name = "Ali", Family = "Bayat" } };
                }
                else
                {
                    u.ItemsSource = new ObservableCollection<Car1> { new Car1 { Name = "BMW", Model = "518", Color = "Red" } };
                }
            };
        }

您的自定义 DataGrid 的 SainaAccessEntity 属性 绑定到视图模型的 SainaAccessEntity 属性 但是当 selection 在组合框更改。

视图模型的表 属性 应该 return ObservableCollection 而不是 ObservableCollection:

public class GridViewWindowViewModel : INotifyPropertyChanged
{
    public GridViewWindowViewModel()
    {
        Tables = new ObservableCollection<SainaAccessEntity>
            {
                new SainaAccessEntity { TableName = "Person" },
                new SainaAccessEntity { TableName = "Car" },
            };
        SainaAccessEntity = Tables[0];
    }

    private SainaAccessEntity _SainaAccessEntity;

    public SainaAccessEntity SainaAccessEntity
    {
        get { return _SainaAccessEntity; }
        set
        {
            if (_SainaAccessEntity != value)
            {
                _SainaAccessEntity = value;
                OnPropertyChanged();
            }
        }
    }

    private ObservableCollection<SainaAccessEntity> _Tables;
    public ObservableCollection<SainaAccessEntity> Tables
    {
        get { return _Tables; }
        set
        {
            if (_Tables != value)
            {
                _Tables = value;
                OnPropertyChanged();
            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged = delegate { };
    private void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}

然后您应该将 ComboBox 的 SelectedItem 属性 绑定到视图模型的 SainaAccessEntity 属性 并将 ComboBox 的 DisplayMemberPath 属性 设置为 "TableName":

<ComboBox Margin="0,5.694,0,0" Grid.Row="1" ItemsSource="{Binding Tables, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" 
                  SelectedItem="{Binding SainaAccessEntity, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                  DisplayMemberPath="TableName"></ComboBox>

通过这些更改,当您 select ComboBox 中的项目时,DataGrid 的 ItemsSource 应该会按预期更改。