【问题标题】:How to create a Dependency property on an existing control?如何在现有控件上创建依赖属性?
【发布时间】:2010-10-15 08:25:38
【问题描述】:

几天来,我一直在阅读 Dependency 属性,并了解它们如何检索值,而不是像在 CLR 属性中那样设置/获取它们。如果我错了,请随时纠正我。

据我了解,从 DependencyObject 派生的所有 WPF 控件(如 TextBlock、Button 等)也将包含依赖属性来存储其值,而不是使用 CLR 属性。这样做的好处是在使用动画的情况下覆盖本地值,或者在根本没有设置本地值的情况下继承值等。

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

1) 是否可以在现有 WPF 控件上创建我自己的依赖属性?假设我想要 WPF Textblock 类上的整数类型的依赖属性?或者我是否必须创建一个从 TextBlockBase 派生的新类才能在上面创建我的依赖属性?

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

希望有人能帮我举出这两个例子... 非常感谢, 卡夫

【问题讨论】:

    标签: .net wpf dependency-properties


    【解决方案1】:

    您可以使用attached properties

    定义您的属性 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>
    

    【讨论】:

    • 谢谢,这也是一个不错的选择,我很快就会尝试。
    【解决方案2】:

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

    在您的情况下,我建议派生新类型。主要是因为您的逻辑与此类型绑定。这是继承的基础,不受依赖属性的约束。

    在 AttachedProperty 的情况下,您只是给另一个对象在不同对象中的值的 awerness。像 Grid.Row 这样的东西让 Grid 了解它的孩子以及它应该如何定位它。设置此属性的对象什么都不知道。

    【讨论】:

    • 谢谢。为什么我要创建 dp?我读到有些人创造了他们自己的。我想看一个创建自己的 dp 有意义的示例...
    【解决方案3】:

    这是一个关于 Run 元素的 ovveride 的示例:

    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>
    

    【讨论】:

      猜你喜欢
      • 2010-11-10
      • 1970-01-01
      • 1970-01-01
      • 2012-12-06
      • 2011-05-25
      • 2011-06-15
      • 1970-01-01
      • 2022-12-17
      • 1970-01-01
      相关资源
      最近更新 更多