Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/315.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何将对象提供给UserControl';谁的构造函数?_C#_Wpf - Fatal编程技术网

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