我有一个简单的wpf项目,它包含一个包含Employees的ObservableCollection和3个文本框的列表框。
我做了一个"模型"类以及将Employee等属性对象链接到MainWindow的类。 Employee类的属性称为" CurrentEmployee"。
我将一个Model对象初始化为Window并将其命名为" boundModel"。当在列表框中更改选择时,我想要" boundModel.CurrentEmployee"更改为选择的员工,以及3个文本框也更改为员工的属性。我目前设置" boundModel.CurrentEmployee"在列表框中选择的任何名称。当列表框选择发生变化时,boundModel.CurrentEmployee就变了!不幸的是,它没有在MainWindow上更新!
我想将boundModel.CurrentEmployee绑定到3个文本框。我想这样做,这样当我创建另一个类时,我可以通过Model类将该类链接到更多的UI控件。这是可能的,还是以任何方式有效的?我的窗户形式背景在这里看起来几乎没用!
提前致谢!
主窗口后端
public partial class MainWindow : Window
{
Model boundModel;
public MainWindow()
{
boundModel = new Model();
InitializeComponent();
this.DataContext = boundModel;
lb_Employees.ItemsSource = boundModel.EmployeeCollection;
}
private void lb_Employees_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
boundModel.CurrentEmployee = (Employee)lb_Employees.SelectedItem;
}
}
主窗口XAML
<ListBox x:Name="lb_Employees" SelectionChanged="lb_Employees_SelectionChanged">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<TextBox x:Name="tb_Name" Text="{Binding boundModel.Name}"/>
<TextBox x:Name="tb_Age" Text="{Binding Age}"/>
<TextBox x:Name="tb_Kids" Text="{Binding HasKids}"/>
员工
class Employee : System.ComponentModel.INotifyPropertyChanged
{
private string name;
private int age;
private bool hasKids;
public string Name
{
get{return name;}
set
{
name = value;
Notify("Name");
}
}
public int Age
{
get{return age;}
set
{
age = value;
Notify("Age");
}
}
public bool HasKids
{
get{return hasKids;}
set
{
hasKids = value;
Notify("HasKids");
}
}
public Employee(string name, int age, bool haskids)
{
this.Name = name;
this.Age = age;
this.HasKids = haskids;
}
public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
private void Notify(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this,
new System.ComponentModel.PropertyChangedEventArgs(propertyName));
}
}
模型
class Model : System.ComponentModel.INotifyPropertyChanged
{
public ObservableCollection<Employee> EmployeeCollection = new ObservableCollection<Employee>();
private Employee currentemployee;
public Employee CurrentEmployee
{
get {return currentemployee;}
set
{
currentemployee = value;
Notify("Employee");
}
}
public Model()
{
EmployeeCollection.Add(new Employee("Tom Smith", 40, true));
EmployeeCollection.Add(new Employee("Beth Smith", 38, true));
EmployeeCollection.Add(new Employee("Steph Rodriguez", 25, false));
}
public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
private void Notify(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this,
new System.ComponentModel.PropertyChangedEventArgs(propertyName));
}
}
答案 0 :(得分:0)
此媒体资源的名称为CurrentEmployee
,而非Employee
。
public Employee CurrentEmployee
{
get {return currentemployee;}
set
{
currentemployee = value;
//Notify("Employee");
Notify("CurrentEmployee");
}
}
boundModel
是一个私人领域。您无法绑定到任何私有内容,也无法绑定到任何类型的字段。
它也是(或应该)与DataContext
相同的对象。这些绑定转到DataContext
以查找其路径中指定的属性。因此,如果要绑定到DataContext.CurrentEmployee.Name
,请执行以下操作:
<TextBox x:Name="tb_Name" Text="{Binding CurrentEmployee.Name}"/>
<TextBox x:Name="tb_Age" Text="{Binding CurrentEmployee.Age}"/>
<TextBox x:Name="tb_Kids" Text="{Binding CurrentEmployee.HasKids}"/>
我实际上建议删除boundModel
并执行此操作(我不会将我的viewmodel模型命名为,但您已经这样做了):
public MainWindow()
{
InitializeComponent();
ViewModel = new Model();
}
public Model ViewModel {
get { return DataContext as Model; }
set { DataContext = value; }
}
我将在XAML中绑定ItemsSource,并通过绑定设置CurrentEmployee:
<ListBox
x:Name="lb_Employees"
ItemsSource="{Binding EmployeeCollection}"
SelectedItem="{Binding CurrentEmployee}"
>
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
哎呀,另一种简化方法:ItemTemplate没有做足以证明其存在的理由。您可以改为使用DisplayMemberPath
:
<ListBox
x:Name="lb_Employees"
ItemsSource="{Binding EmployeeCollection}"
SelectedItem="{Binding CurrentEmployee}"
DisplayMemberPath="Name"
/>
现在我们已经省去了代码隐藏与viewmodel直接交互的所有地方,我们也可以免除ViewModel
属性。它不再需要了。 Codebehind不是坏的东西,但如果你正确地做WPF,你经常会发现那里几乎没有必要做任何事情。