【发布时间】:2018-02-15 07:26:34
【问题描述】:
我有两个具有相同 Name 和 Position 属性的类。 DataGrid 中的 ComboBox 具有从数据库中获取的 StaffMember 类的列表。它仅显示名称,但在选择时,Name 和 Position 属性应在绑定到另一个类的 ObservableCollection 的 DataGrid 中更改 - Person。
到目前为止,我使用组合框的 SelectionChanged 事件来浏览 VisualTree,访问父 DataContext 并一次更改两个属性。
有什么不同的方法吗?
更新。这是一张说明图:
我从第三方服务获取名称和职位,并在组合框中显示名称。当用户选择一个名称时,UI 应该更新表中的 Name 和 Position 属性。该表还具有现实世界中的年龄和许多其他列/属性。这就是为什么有两个类:从数据库中选择的名称/职位列表和作为表的 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();
}
【问题讨论】:
-
只有我不明白 OP 想要达到什么目标吗?
-
您的视图模型应该有一个
SelectedPerson属性,ComboBox的SelectedItem属性绑定到该属性。然后你的TextBox的名字和位置就绑定到SelectedPerson.Name和SelectedPerson.Position。您永远不必接触代码隐藏。 -
如果您唯一的问题是是否有不同的方法来解决它,那么这太宽泛了。您要求进行代码审查。有another site。
-
我知道你想要一个级联组合框:stackoverflow.com/questions/42871459/…