WPF组合控件

6
我正在尝试在WPF中创建一个可重用的UserControl,其中包含一个Label和一个TextBox。我想为我的UserControl添加属性,以便将两个子控件的文本字段上移到父级以便于绑定。我读到需要通过向DependencyProperties添加owner来进行一些操作。这是我的代码。看起来很接近但还不够完美。有什么建议吗?
这是Xaml:
<UserControl x:Class="MAAD.AircraftExit.Visual.LabelTextBox"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Height="20" Width="300">
    <DockPanel>
        <TextBlock Text="{Binding Path=Label, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}" DockPanel.Dock="Left" TextAlignment="Right" Width="122" />
        <TextBlock Text=": " DockPanel.Dock="Left"/>
        <TextBox Text="{Binding Path=Text, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}" />
    </DockPanel>
</UserControl>

代码如下:

public partial class LabelTextBox : UserControl
{
    public static readonly DependencyProperty LabelProperty = DependencyProperty.Register("Label", typeof(string), typeof(LabelTextBox));
    public string Label
    {
        get { return (string)GetValue(LabelProperty); }
        set { SetValue(LabelProperty, value); }
    }

    public static readonly DependencyProperty TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(LabelTextBox));
    public string Text
    {
        get { return (string)GetValue(TextProperty); }
        set { SetValue(LabelTextBox.TextProperty, value); }
    }

    public LabelTextBox()
    {
        InitializeComponent();

        ClearValue(HeightProperty);
        ClearValue(WidthProperty);
    }
}

编辑:这是最终可工作的代码。我切换到了相对源绑定。

1
我最初也尝试了同样的方法,认为这就是所谓的所有者概念。不幸的是,我遇到了相同的问题,最终也不得不使用绑定。此外,我的非依赖属性在传播属性更改通知方面有不同的自定义解决方案。 - jpierson
2个回答

6

绑定是一种非常好的方法:

XAML:

<UserControl x:Class="testapp.LabelTextBox "
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="300" Width="300" x:Name="This">
<DockPanel>
    <TextBlock DockPanel.Dock="Left" TextAlignment="Right" Width="70" Name="label" Text="{Binding Label, ElementName=This}"  />
    <TextBlock Text=": " DockPanel.Dock="Left" />
    <TextBox Name="textBox" Text="{Binding Text, ElementName=This}" />
</DockPanel>

代码后台:

    public partial class LabelTextBox : UserControl
{
    public LabelTextBox()
    {
        InitializeComponent();
        Label = "Label";
        Text = "Text";
    }
    public static readonly DependencyProperty LabelProperty = DependencyProperty.Register("Label", typeof(string), typeof(LabelTextBox), new FrameworkPropertyMetadata(LabelPropertyChangedCallback));
    private static void LabelPropertyChangedCallback(DependencyObject controlInstance, DependencyPropertyChangedEventArgs args)
    {
    }
    public string Label
    {
        get { return (string) GetValue(LabelProperty); }
        set { SetValue(LabelProperty, value); }
    }

    public static readonly DependencyProperty TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(LabelTextBox), new FrameworkPropertyMetadata(TextPropertyChangedCallback));
    private static void TextPropertyChangedCallback(DependencyObject controlInstance, DependencyPropertyChangedEventArgs args)
    {
    }
    public string Text
    {
        get { return (string) GetValue(TextProperty); }
        set { SetValue(LabelTextBox.TextProperty, value); }
    }
}

感谢您的代码,我在尝试使用它时得到了以下输出:System.Windows.Data Error: 4 : 找不到与引用 'ElementName=This' 相关绑定的源。BindingExpression:Path=Label; DataItem=null; target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String')。 - Jake Pearson
抱歉,我已经解决了。你将“This”定义为控件的名称。谢谢! - Jake Pearson

1

我还没有仔细查看您的实现不起作用的原因,但我真的不明白为什么您要那样做。为什么不在UserControl上定义所需的依赖属性,然后绑定到它们呢?

public static readonly DependencyProperty LabelTextProperty = ...;

然后在你的XAML中:

<Label Content="{Binding LabelText}"/>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接