我有两个具有相同Name和Position属性的类。 DataGrid中的ComboBox具有从数据库中获取的StaffMember类列表。它仅显示名称,但在选择时,Name和Position属性应在DataGrid中更改为绑定到另一个类的ObservableCollection - Person。
到目前为止,我使用组合框的SelectionChanged事件来浏览VisualTree,访问父DataContext并一次更改两个属性。
有不同的方法吗?
更新。这是一张说明图片:
我从第三方服务获取名称和位置,并在组合框中显示名称。当用户选择名称时,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();
}
答案 0 :(得分:0)
混合MVVM和代码隐藏不是一个好主意。 您在Person和StaffMember类中有重复的数据。
如何在Person类中拥有StaffMember属性?
id