我试图用WPF绑定来解决一些问题,所以我创建了一个简单的项目 . 这是代码:
public class Person : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public int Age {
get { return age; }
set {
age = value;
FirePropertyChanged("Age");
}
}
public string Name
{
get { return name; }
set
{
name = value;
FirePropertyChanged("Name");
}
}
private void FirePropertyChanged(string v)
{
if(PropertyChanged !=null)
PropertyChanged(this, new PropertyChangedEventArgs(v));
}
private int age;
private string name;
}
我的viewmodel包含Person的ObservableCollection,以及跟踪所选Person的单个Person .
我将listbox的ItemsSource绑定到ObservableCollection,将SelectedItem绑定到单个Person,名为CurrentPerson . 另外,我已将TextBox绑定到CurrentPerson.Name .
代码工作正常,但每当我更改TextBox的内容时 - 我的列表框也会更改 . 而且无论listbox \ selecteditem上的“OneWay,TwoWay,OneWayToSource”绑定模式的组合如何,我都无法阻止列表框从CurrentPerson更新 .
我该如何防止这种行为?我想只使用VM的ICommand接口从CurrentPerson更新列表框 .
3 回答
只有一个
Person
对象的副本在ListBox.ItemsSource
和TextBox.Text
中使用,因此从一个位置自然更新该对象也将反映另一个位置的变化 .两个简单的解决方案是
将
TextBox.Text
上的BindingMode
更改为Explicit
,因此在您告诉它之前它不会更新Person对象为
TextBox.Text
使用单独的字符串属性,并在命令执行时将其复制到SelectedPerson.Name
我个人更喜欢第二个选项,因为我'm not a big fan of bindings that don'吨准确地反映了UI组件后面的数据对象,它允许用户在不重置TextBox值的情况下更改
SelectedItem
.有关第二个选项的示例,您的ViewModel可能如下所示:
UpdatePersonName
命令将执行的位置并且
CanExecute
只会返回true我不确定我是否正确地遵循了这个问题 . 所以,我们有一个Person类
我们有一个视图模型
xaml是
然后我将视图模型绑定到视图
每当我更改文本框中的值时,它都会正确更新名称 . 我尝试为列表更改添加处理程序,但它不会被触发 .
如果它与你的问题陈述不一样,你能评论一下吗?
如果您想控制保存/更新的时间和内容,您显然需要一个用于编辑Person模型的ViewModel .
在列表框中选择人员时,必须将人员的id(避免将对象本身传递)传递给绑定到应编辑的属性的
PersonEditViewModel
,将人员数据加载到PersonEditViewModel
然后进行编辑 . 点击"Save"按钮后,它应该提交更改并更新数据库或用于持久性的任何内容 .使用事件/消息来回传递值/事件,或使用导航方法(如Prism中的
INavigationAware
接口) .