如何在现有控件上创建依赖属性?

9

我已经阅读了几天关于依赖属性的资料,明白它们如何检索值而不是像CLR属性一样进行设置/获取。如果我有错误,请随时纠正。

据我所知,所有WPF控件(例如TextBlock、Button等)都派生自DependencyObject,并包含依赖属性来存储它们的值,而不是使用CLR属性。这样做的好处是在使用动画时覆盖本地值,在未设置任何本地值时继承值等。

现在我正在尝试创建一些示例来创建和使用自己的dp。

1)是否可以在现有的WPF控件上创建自己的依赖属性?比如说,我想在WPF Textblock类上创建一个整数类型的依赖属性?还是我必须创建一个派生自TextBlockBase的新类,以便在其中创建我的依赖属性?

2)无论哪种情况,假设我已经在WPF textblock类上创建了一个依赖属性。现在我想通过将标签的内容绑定到TextBlock的依赖属性来利用它。这样,标签始终会显示TextBlock的dp的实际值,无论它是继承的还是本地设置的。

希望有人能帮助我解决这两个问题...非常感谢, Kave

3个回答

8
您可以使用附加属性来实现此功能。
定义您的属性MyInt:

namespace WpfApplication5
{
    public class MyProperties
    {
        public static readonly System.Windows.DependencyProperty MyIntProperty;

        static MyProperties()
        {
            MyIntProperty = System.Windows.DependencyProperty.RegisterAttached(
                "MyInt", typeof(int), typeof(MyProperties));
        }

        public static void SetMyInt(System.Windows.UIElement element, int value)
        {
            element.SetValue(MyIntProperty, value);
        }

        public static int GetMyInt(System.Windows.UIElement element)
        {
            return (int)element.GetValue(MyIntProperty);
        }
    }
}

绑定标签内容:


<Window x:Class="WpfApplication5.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:WpfApplication5"
    Title="Window1" Height="300" Width="300">
    <Grid>
        <Label Margin="98,115,51,119" Content="{Binding Path=(local:MyProperties.MyInt), RelativeSource={x:Static RelativeSource.Self}}" local:MyProperties.MyInt="42"/>
    </Grid>
</Window>

谢谢,这也是一个不错的选择,我很快就会尝试。 - Houman

1

您不能将DependencyProperties添加到现有类型中。虽然您可以使用AttachedProperty,但使用它和派生新类型的逻辑完全不同。

在您的情况下,我建议派生新类型。主要是因为您的逻辑与此类型绑定。这是继承背后的基本原理,与Dependency属性无关。

在使用AttachedProperty的情况下,您只是让另一个对象意识到不同对象中的值。类似Grid.Row这样的东西会让Grid意识到其子项以及如何定位它。设置此属性的对象不知道任何内容。


谢谢。为什么我要创建dp呢?我已经读到有些人会自己创建dp。我想看一个例子,看看何时创建自己的dp是有意义的... - Houman

0

这里是一个关于 Run 元素覆盖的示例:

using System;
using System.Windows;
using System.Windows.Documents;

namespace MyNameSpace.FlowDocumentBuilder
{
    public class ModifiedRun : Run
    {
        static DateRun()
        {
            TextProperty.OverrideMetadata(typeof(DateRun),new FrameworkPropertyMetadata(string.Empty,FrameworkPropertyMetadataOptions.Inherits,null,CoerceValue));
        }

        private static object CoerceValue(DependencyObject d, object basevalue)
        {
            return "AAAAAAAA";
        }
    }
}

对应的 XAML 代码如下:

<FlowDocument xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                      ColumnWidth="400"
                      FontSize="14"
                      FontFamily="Arial"
xmlns:local="clr-namespace:MyNameSpace.FlowDocumentBuilder;assembly=MyNameSpace.FlowDocumentBuilder"
>

<Paragraph><local:ModifiedRun Text="BBBBBBBBBB"/></Paragraph>

</FlowDocument>

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