【发布时间】:2020-02-13 19:34:43
【问题描述】:
我和一个队友正在讨论在 WPF 中创建用户控件的不同方法。具体来说,讨论的背景是从头开始构建的数字向上/向下用户控件。它由一个用于标题的标签、一个用于值的文本框、一个用于单位的标签和 2 个用于向上/向下操作的按钮组成。最终目标是绑定到此用户控件从屏幕视图模型中公开的属性。
用户控件的TextBox xaml声明如下:
<TextBox x:Name="Textbox" Text="{Binding TextboxValue, FallbackValue=0}" Width="100" Height="40" TextAlignment="Left" FontSize="28" VerticalAlignment="Center" BorderBrush="Black" BorderThickness="2"/>
TextBoxes Text 属性绑定到用户控件视图的代码隐藏。代码隐藏相关部分的片段如下所示。
public static readonly DependencyProperty TextboxValueProperty = DependencyProperty.Register("TextboxValue",
typeof(double), typeof(IncrementDecrementTextbox), new PropertyMetadata(12.0d, new PropertyChangedCallback(OnTextboxValueChanged)));
public IncrementDecrementTextbox()
{
InitializeComponent();
this.DataContext = this;
}
public double TextboxValue
{
get
{
return (double)GetValue(TextboxValueProperty);
}
set
{
SetValue(TextboxValueProperty, value);
NotifyTextboxValueUpdated();
}
}
private static void OnTextboxValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
IncrementDecrementTextbox control = d as IncrementDecrementTextbox;
control.OnTextboxValueChanged(e);
}
private void OnTextboxValueChanged(DependencyPropertyChangedEventArgs e)
{
TextboxValue = Convert.ToDouble(e.NewValue);
}
public event EventHandler TextboxValueUpdated;
private void NotifyTextboxValueUpdated()
{
TextboxValueUpdated?.Invoke(this, EventArgs.Empty);
}
这个用户控件的实现让我感到困惑。我不明白为什么在视图和它的代码隐藏部分之间使用数据绑定。我认为,由于代码隐藏和相应的 xaml 视图本质上是一回事,因此人们希望通过设置元素的 x:Name 属性直接从后面的代码访问在 xaml 中声明的元素。但是,我可能会遗漏一些东西。
在创建用户控件时,视图和代码隐藏之间的绑定是一种标准做法吗?如果没有,有更好的方法吗?
谢谢!
【问题讨论】:
-
在后面的代码中创建依赖属性,然后绑定到视图上。然后你可以绑定到用户控件属性,如果你愿意的话。
-
首先:您应该永远将您的
UserControl.DataContext属性设置为this。 using 控件的代码需要能够设置它,以便它们可以将其视图模型属性绑定到控件的属性。除此之外,如何传播值取决于您,但一种常见的策略是使用绑定来指定带有RelativeAncestor标记的源。您也可以按名称指定源,但这可能会再次干扰客户端代码(即,如果您的客户端代码也想设置名称)。有关该主题的广泛讨论,请参阅标记的重复项。 -
昨晚我阅读了关于在 Pro WPF 4.5 In C# 中创建自定义用户控件的第 18 章,这几乎回答了我的任何问题。绝对不想将 DataContext 设置为此。使用绑定在视图和代码隐藏之间进行绑定是完全没问题的,并且对于使用用户控件的绑定工作来说实际上是必要的。在控件视图中使用 RelativeAncestor 标记是我在那一章中看到的一个建议。
标签: c# wpf xaml data-binding code-behind