![](/img/trans.png)
[英]Difference between setting DataContext=this in constructor and Binding to {RelativeSource Self} in WPF?
[英]Setting WPF Window DataContext to RelativeSource Self
如果我在構造函數中將Window的DataContext設置this
, 以及在XAML 中將 {Binding RelativeSource={RelativeSource Self}}
為I,那么我可以通過在其中放置一個斷點來看到DataContext引用了正確的對象實例(即MainWindow)。代碼隱藏的Loaded事件。 但是,Window的子元素exampleButton的Command綁定為null。 斷言失敗。
當我刪除XAML DataContext設置(僅依賴於構造函數設置)時,exampleButton的Command會正確使用DataContext。
為什么在XAML場景中exampleButton的Command綁定為null?
MainWindow.xaml
<Window x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Example"
SizeToContent="WidthAndHeight"
x:Name="mainWindow"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
Loaded="mainWindow_Loaded">
<Button x:Name="exampleButton" Command="{Binding Path=ExampleCommand}" Content="Click"/>
</Window>
MainWindow.xaml.cs
public partial class MainWindow : Window
{
public ICommand ExampleCommand { get; }
public MainWindow()
{
InitializeComponent();
DataContext = this;
ExampleCommand = new DelegateCommand(x => { throw new ApplicationException(); });
}
private void mainWindow_Loaded(object sender, RoutedEventArgs e)
{
Debug.Assert(mainWindow == this);
Debug.Assert(mainWindow.DataContext == this);
Debug.Assert(exampleButton.DataContext == this);
Debug.Assert(exampleButton.Command == ExampleCommand); //<-- FAIL
}
}
在InitializeComponent
之前設置ExampleCommand
和DataContext
:
DataContext = this;
ExampleCommand = new DelegateCommand(x => { throw new ApplicationException(); });
InitializeComponent();
還要注意,使用DataContext="{Binding RelativeSource={RelativeSource Self}}"
或DataContext = this;
沒有區別DataContext = this;
,如果您在initializecomponent之前設置了datacontext。
為什么在XAML場景中exampleButton的Command綁定為null?
因為ExampleCommand
屬性在InitializeComponent()
方法返回並設置DataContext
屬性時實際上具有null值。
如果要在此之后將屬性設置為新值,則該類必須實現INotifyPropertyChanged接口,以使目標屬性自動刷新:
public partial class MainWindow : Window, INotifyPropertyChanged
{
public MainWindow()
{
InitializeComponent();
ExampleCommand = new RelayCommand<object>(x => { throw new ApplicationException(); });
}
private ICommand _exampleCommand;
public ICommand ExampleCommand
{
get { return _exampleCommand; }
set { _exampleCommand = value; NotifyPropertyChanged(); }
}
private void mainWindow_Loaded(object sender, RoutedEventArgs e)
{
Debug.Assert(exampleButton.DataContext == this);
Debug.Assert(exampleButton.Command == ExampleCommand); //<-- FAIL
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.