依赖属性链

6
假设我有一个自定义控件,它包装了另一个控件(例如MyCustomButton)。我公开一个名为Content的属性,用于包装内部控件:
    public object Content
    {
        get { return innerControl.Content; }
        set { innerControl.Content = value; }
    }

为了让消费者绑定到这个属性,我需要为它定义一个DependencyProperty:
 public static DependencyProperty ContentProperty = DependencyProperty.Register("Content", typeof (object), typeof (MyCustomButton));

但是现在我需要我的属性定义使用GetValue/SetValue:

    public object Content
    {
        get { return GetValue(ContentProperty); }
        set { SetValue(ContentProperty, value); }
    }

所以我不再包装内部控件的值。

我可以定义PropertyMetadata来处理DependencyProperty的PropertyChanged事件,但这样我需要大量的管道代码来保持值同步并防止改变时的无限循环。

更新:我不能仅仅从Button派生,因为我的UserControl有各种其他问题。

有更好的方法吗?

1个回答

2
好的,根据您将按钮包装在用户控件中的具体原因,您可以定义一个从按钮继承的自定义控件。然后,您可以覆盖要定义自定义控件行为的方法和属性,而不是包装按钮并公开您想要的包装方法和属性。这样,您将获得按钮的所有功能,而无需重新发明轮子。
这里有一个谷歌链接,向您介绍了这个过程(我找到的第一个链接 - 还有很多):http://knol.google.com/k/creating-custom-controls-with-c-net# 如果用户控件还有其他问题,则这可能不适合您,但我提供此答案是因为您提到它的唯一目的是包装按钮。如果所讨论的控件仅意味着成为更特定的包装/继承控件(即在您的情况下为按钮),则我个人更喜欢创建自定义控件并继承而不是用户控件和包装。
编辑:根据更新的问题...
您可以按照以下方式进行操作。这是您的用户控件客户端的XAML:
<Grid>
    <local:MyControl ButtonContent="Click Me!"/>
</Grid>
</Window>

这是用户控件本身的XAML代码:
```

这里是用户控件本身的XAML代码:

```
 <UserControl x:Class="GuiScratch.MyControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:GuiScratch"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <Grid>

        <StackPanel>
            <ContentControl Content="Asdf"/>
            <Button Content="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:MyControl}},Path=ButtonContent}"/>
        </StackPanel>

    </Grid>
</UserControl>

以下是代码:

public partial class MyControl : UserControl
{

    public static readonly DependencyProperty ButtonContentProperty = 
    DependencyProperty.Register("ButtonContent", typeof(object), typeof(MyControl), 
    new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.AffectsRender));

    public object ButtonContent
    {
        get { return (object)GetValue(ButtonContentProperty); }
        set { SetValue(ButtonContentProperty, value); }
    }

    public MyControl()
    {
        InitializeComponent();
    }
}

因此,您不需要通过代码处理绑定。您的客户端XAML绑定到您的依赖属性,用户控件本身的XAML也是如此。通过这种方式,它们共享依赖属性设置。我在我的小草稿本中运行了这个示例,结果是(至少是我理解的)您所寻找的内容。主窗口将用户控件显示为一个带有文本“ Asdf”和一个文本为“ Click Me!”的按钮的堆栈面板。

用户控件还有其他问题。更新的问题。 - Jeff
你是否特别想使用用户控件的“Content”属性?如果不是,你可以暴露一个不同的依赖属性,并将用户控件中的某些东西绑定到它的值。 - Erik Dietrich
我不在乎它叫什么。但是我希望属性的值被绑定到内部控件上的特定内容。 - Jeff

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