WPF Make ComboBox选择触发多个属性更改

时间:2017-09-06 17:45:58

标签: c# wpf combobox datagrid

我有两个具有相同Name和Position属性的类。 DataGrid中的ComboBox具有从数据库中获取的StaffMember类列表。它仅显示名称,但在选择时,Name和Position属性应在DataGrid中更改为绑定到另一个类的ObservableCollection - Person。

到目前为止,我使用组合框的SelectionChanged事件来浏览VisualTree,访问父DataContext并一次更改两个属性。

有不同的方法吗?

更新。这是一张说明图片:

enter image description here

我从第三方服务获取名称和位置,并在组合框中显示名称。当用户选择名称时,UI应更新表中的名称和位置属性。该表还具有Age和现实世界中的许多其他列/属性。这就是为什么有两个类:来自数据库的名称/位置列表以供选择,以及一个类是表的ItemSource。当人们有相同的名字但位置不同时,我也必须处理案件。希望这能更好地解释这个问题。

 public class StaffMember : NotifyObject
    {
        private string _name;
        public string Name
        {
            get { return _name; }
            set { _name = value; OnPropertyChanged("Name"); }
        }

        private string _position;
        public string Position
        {
            get { return _position; }
            set { _position = value; OnPropertyChanged("Position"); }
        }

    }

    public class Person : NotifyObject
    {
        private string _name;
        public string Name
        {
            get { return _name; }
            set { _name = value; OnPropertyChanged("Name"); }
        }

        private string _position;
        public string Position
        {
            get { return _position; }
            set { _position = value; OnPropertyChanged("Position"); }
        }

        public double Age { get; set; }
    }

视图模型:

    public class ViewModel : NotifyObject
    {
        public ObservableCollection<Person> SelectedPeople { get; set; }
        public List<StaffMember> Staff { get; set; }

        public ViewModel()
        {
            Staff = new List<StaffMember>
            {
                new StaffMember { Name = "Sigmund Freud", Position = "Psychologist"},
                new StaffMember { Name = "Louis Armstrong", Position = "Musician"},
                new StaffMember { Name = "John Doe", Position = "Superviser"},
                new StaffMember { Name = "John Doe", Position = "Manager"},
            };

            SelectedPeople = new ObservableCollection<Person> {
                new Person { Name = "Sigmund Freud", Position = "123", Age= 161 },
                new Person(),
                new Person() };
        }
    }

    public abstract class NotifyObject : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        protected void OnPropertyChanged(string property)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(property));
        }

        public void RaiseProperychanged(string propertyName)
        {
            OnPropertyChanged(propertyName);
        }
    }

XAML:

<Grid>
        <DataGrid ItemsSource="{Binding SelectedPeople}"
                  AutoGenerateColumns="False"
                  CanUserAddRows="False">
            <DataGrid.Columns>
                <DataGridTemplateColumn Header="Name">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <ComboBox x:Name="ComboBoxSelect" ItemsSource="{Binding ElementName=TheMainWindow, Path=DataContext.Staff}"
                                      SelectedValue="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGridRow}, Path=DataContext.Name, Mode=TwoWay}"
                                      DisplayMemberPath="Name"
                                      SelectedValuePath="Name"
                                      SelectionChanged="ComboBoxSelect_SelectionChanged"/>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
                <DataGridTextColumn Header="Position" Binding="{Binding Position, Mode=TwoWay}"/>
                <DataGridTextColumn Header="Age" Binding="{Binding Age}"/>
            </DataGrid.Columns>
        </DataGrid>
    </Grid>

代码隐藏:

 private void ComboBoxSelect_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            var comboBox = sender as ComboBox;
            var parent = sender as DependencyObject;
            while (!(parent is DataGridCell))
            {
                parent = VisualTreeHelper.GetParent(parent);
                if (parent is null) return;
            }
            var cell = parent as DataGridCell;
            if (cell == null) return;
            var person = cell.DataContext as Person;
            if (person == null) return;
            person.Position = ((StaffMember)comboBox.SelectedItem).Position.ToString();
        }

1 个答案:

答案 0 :(得分:0)

混合MVVM和代码隐藏不是一个好主意。 您在Person和StaffMember类中有重复的数据。

如何在Person类中拥有StaffMember属性?

id