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

时间:2016-12-27 08:06:26

标签: wpf xaml wpfdatagrid

这是一个示例代码:

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));
        }

    }

这是Model 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; }
}

主窗口XAML:

<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中有自定义DataGrid,它有一个定义表名的属性,我想在更改此属性时动态更改ItamsSource ...

2 个答案:

答案 0 :(得分:2)

这里你的属性'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" } };
                }
            };
        }

答案 1 :(得分:2)

自定义DataGrid的SainaAccessEntity属性绑定到视图模型的SainaAccessEntity属性,但是当ComboBox中的选择发生更改时,您永远不会设置此属性。

视图模型的Tables属性应返回ObservableCollection&lt; SainaAccessEntity&gt;而不是ObservableCollection&lt; string&gt;:

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属性设置为&#34; TableName&#34;:

<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>

通过这些更改,当您在ComboBox中选择项目时,应按预期更改DataGrid的ItemsSource。