我有一个UserControl
,它将一个属性绑定到一个控件,这似乎很有效:
<UserControl x:Class="MyUserControl" Name="control">
<TextBox Text="{Binding SomeData, ElementName=control}" />
但是,获取此特定属性的信息需要设置另一个属性,该属性在主窗口中的InitializeComponent
之后设置。不过,我的UserControl
的构造函数在InitializeComponent
中被调用,导致NullReferenceException
:
public MainWindow() {
InitializeComponent(); // <-- here my UserControl is instatiated and needs Settings
Settings = new Settings();
MyUserControl.Settings = Settings; // <-- only here do we set the Settings object (which is needed in UserControl's constructor!
}
public MyUserControl {
public string SomeData {
get {
return Settings.Get("someSetting");
}
}
}
我该如何解决这个问题?或者我的体系结构是错误的(刚开始使用WPF和数据绑定(。
您应该将MyUserControl
绑定到MainWindow.Settings
属性,该属性应该是DependencyProperty
。然后将初始化从MyUserControl
的构造函数移动到MyUserControl.Loaded
事件处理程序。执行此处理程序时,绑定的Settings
值将可用。
或者定义一个CCD_ 12。
主窗口.xaml.cs
partial class MainWindow : Window
{
public static readonly DependencyProperty SettingsProperty = DependencyProperty.Register(
"Settings",
typeof(Settings),
typeof(MainWindow),
new PropertyMetadata(default(Settings)));
public Settings Settings
{
get => (Settings) GetValue(MainWindow.SettingsProperty);
set => SetValue(MainWindow.SettingsProperty, value);
}
public MainWindow()
{
InitializeComponent();
this.Settings = new Settings();
}
}
MyUserControl.xaml.cs
partial class MyUserControl : UserControl
{
public static readonly DependencyProperty SettingsProperty = DependencyProperty.Register(
"Settings",
typeof(Settings),
typeof(MyUserControl),
new PropertyMetadata(default(Settings), OnCurrentReadingChanged));
public Settings Settings
{
get => (Settings) GetValue(MyUserControl.SettingsProperty);
set => SetValue(MyUserControl.SettingsProperty, value);
}
public MyUserControl()
{
InitializeComponent();
this.Loaded += Initialize;
}
private static void OnCurrentReadingChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
Settings settings = (d as MyUserControl).Settings;
// TODO: Initialize using this.Settings
}
public Initialize(object sender, EventArgs e)
{
// TODO: Initialize using this.Settings
}
}
MyUserControl.xaml
<UserControl x:Class="MyUserControl"
Name="control"
Settings="{Binding RelativeSource={RelativeSource AncestorType=MainWindow}, Path=Settings}">
<TextBox Text="{Binding SomeData, ElementName=control}" />
</UserControl>