【发布时间】:2018-05-09 19:05:58
【问题描述】:
我在WPF的默认构造函数中试验了设置DataContext属性的顺序。
<StackPanel>
<ListBox ItemsSource="{Binding MyItems, PresentationTraceSources.TraceLevel=High}"></ListBox>
<TextBlock Text="{Binding SomeText}"></TextBlock>
<TextBlock Text="{Binding SomeNum}"></TextBlock>
<TextBlock Text="{Binding Path=Person.Name}"></TextBlock>
<ListBox ItemsSource="{Binding Path=PersonList}">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}"></TextBlock>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</StackPanel>
1) 在 InitializeComponent 方法
public partial class MainWindow : Window, INotifyPropertyChanged
{
private string someText = "Default text";
public List<string> MyItems { get; set; }
public List<Person> PersonList { get; set; }
public Person Person { get; set; }
public int SomeNum { get; set; }
public string SomeText
{
get
{
return someText;
}
set
{
someText = value;
OnPropertyChanged("SomeText");
}
}
public MainWindow()
{
this.DataContext = this;
MyItems = new List<string>();
PersonList = new List<Person>();
Person = new Person();
InitializeComponent();
/*These changes are not reflected in the UI*/
SomeNum = 7;
Person.Name = "Andy";
/*Changes reflected with a help of INotifyPropertyChanged*/
SomeText = "Modified Text";
/* Changes to the Lists are reflected in the UI */
MyItems.Add("Red");
MyItems.Add("Blue");
MyItems.Add("Green");
MyItems[0] = "Golden";
PersonList.Add(new Person() { Name = "Xavier" });
PersonList.Add(new Person() { Name = "Scott" });
PersonList[0].Name = "Jean";
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
}
public class Person
{
public string Name { get; set; } = "Default Name";
}
在调用InitializeComponent 方法后,属性值的更改不会反映在 UI 中,但使用 INotifyPropertyChanged 的属性除外。到目前为止一切都清楚了。
但是我注意到对列表项的更改也反映在 UI 中。怎么会?
我一直认为,为了反映从集合中添加/删除,我需要 ObservableCollection 并在列表对象上实现INotifyPropertyChanged 以检测这些对象的修改。这是什么意思?
2) 在 InitializeComponent 方法
为什么在 InitializeComponent 之后设置 DataContext 属性对 MVVM 来说是一种不好的做法?能不能描述的更详细一点或者给出一个简单的代码示例?
【问题讨论】:
-
“为什么在 InitializeComponent 之后设置 DataContext 属性对 MVVM 来说是一种不好的做法?”它不是。谁说的?只需确保您的所有属性都会触发 PropertyChanged 事件
-
在stackoverflow.com/a/11479509/7378940下方的评论中“重要的是要注意,如果使用MVVM,则应在调用InitializeComponent()之前设置DataContext,否则您的ViewModel绑定将无法正确设置。InitializeComponent () 调用所有属性绑定 getter,因此如果首先调用它,您的绑定将不会获得正确的值,直到在每个属性上再次调用 NotifyPropertyChanged。"
标签: c# wpf user-interface data-binding datacontext