C# 如何将对象提供给UserControl';谁的构造函数?
我有一个将属性绑定到控件的C# 如何将对象提供给UserControl';谁的构造函数?,c#,wpf,C#,Wpf,我有一个将属性绑定到控件的UserControl,它似乎可以工作: <UserControl x:Class="MyUserControl" Name="control"> <TextBox Text="{Binding SomeData, ElementName=control}" /> 我怎样才能解决这个问题?或者我的体系结构是错误的(刚从WPF和数据绑定开始)。您应该将MyUserControl绑定到MainWindow.Settings属性,该属性应该是Depe
UserControl
,它似乎可以工作:
<UserControl x:Class="MyUserControl" Name="control">
<TextBox Text="{Binding SomeData, ElementName=control}" />
我怎样才能解决这个问题?或者我的体系结构是错误的(刚从WPF和数据绑定开始)。您应该将
MyUserControl
绑定到MainWindow.Settings
属性,该属性应该是DependencyProperty
。然后将初始化从MyUserControl
的构造函数移动到MyUserControl.Loaded
事件处理程序。执行此处理程序时,绑定的设置
值将可用
或者,定义一个
MainWindow.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();
}
}
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.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();
}
}
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>
在XAML中调用无参数构造函数。重新设计控件,使其能够处理稍后设置的设置属性。应将MyUserControl
绑定到main窗口。Settings
属性应为dependencProperty
。然后将初始化从MyUserControl
的构造函数移动到MyUserControl.Loaded
事件处理程序。执行此处理程序时,绑定的设置
值将可用。您没有提供足够的上下文来了解您已经走错了多远,但有关处理方案的各种方法的信息,请参阅标记的重复。简短版本:您的用户控件需要公开一个属性,设置数据可以绑定到该属性,优雅地处理该属性的值为null/un设置,并且具有有效值,并在XAML中绑定到该属性。这是不正确的。一般来说,对于此类数据,不需要处理已加载的
事件。数据应该在XAML中绑定到用户控件公开的属性,并且用户控件应该能够处理默认值以及以后设置的新值。然后,框架将根据绑定在最早方便的时候分配值,这一切都“正常工作”。无需在加载的事件中进行特殊情况处理。什么是“不正确”?那么您关于从XAML调用参数化构造函数的建议也是不正确的。如果您批评他的设计选择,您应该建议使用视图模型。你刚才跟我一样给他展示了一个解决办法。同样可以看到,数据“在XAML中绑定到用户控件公开的属性”。我不知道他为什么在构造函数中处理这些数据。我只是建议将依赖于设置
实例的初始化代码从构造函数移动到加载的
事件-以修复空引用问题(请参见问题)。您关闭了此问题,并引用了主题“从XAML调用参数化构造函数”作为解决方案。我是说,拜托,你从来没说过我说的话,你说的?真的?是的,真的。这个问题与另一个问题完全相同。我既不提倡也不批评在另一个问题中找到的答案。你的想法和主张是错误的。我只是认为这个问题是完全重复的。我对这个问题的OP的建议包含在我在结束问题时的评论中。如果你觉得有更好的答案,一定要把它贴在那里。但所有这些都不会改变我的观点,即您提出的解决方案并不比副本中的答案更好,在某些情况下甚至更糟。我添加了第二个解决方案,它利用了属性ChangedCallback
。