【问题标题】:WPF Composite ControlsWPF 复合控件
【发布时间】:2010-11-04 01:50:30
【问题描述】:

我正在尝试在 WPF 中创建一个具有标签和文本框的可重用用户控件。我想向我的 UserControl 添加属性,以便将两个子控件的 Text 字段向上冒泡到父控件,以便于绑定。我读到我需要通过将所有者添加到 DependencyProperties 来做一些花招。这是我现在的代码。它似乎很接近,但并不完全正确。有什么想法吗?

这是 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);
    }
}

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

【问题讨论】:

  • 我一开始也尝试了同样的事情,并假设这就是所有者概念的全部内容。不幸的是,我遇到了同样的问题,最终也使用了绑定。此外,我的非依赖属性具有用于传播属性更改通知的不同自定义解决方案。

标签: c# wpf data-binding


【解决方案1】:

绑定确实是要走的路:

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 错误:4:找不到引用'ElementName = This'的绑定源。绑定表达式:路径=标签;数据项=空;目标元素是'TextBlock'(名称='');目标属性是“文本”(类型“字符串”)
  • 对不起,我想通了。您将 This 定义为控件的名称。谢谢!!
【解决方案2】:

我还没有仔细研究为什么你的实现不起作用,但我真的不明白你为什么这样做。为什么不直接在 UserControl 上定义你需要的依赖属性然后绑定它们呢?

public static readonly DependencyProperty LabelTextProperty = ...;

然后在您的 XAML 中:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-14
    • 1970-01-01
    • 2010-12-16
    • 1970-01-01
    • 2013-08-29
    • 1970-01-01
    相关资源
    最近更新 更多