XAML 依赖性 属性 与常规属性

XAML Dependency Property vs Regular Properties

如果我有这个:

    public class BoardCalc : FrameworkElement
    {
        public BoardCalc()
        {
            this.Loaded += BoardCalc_Loaded;
        }

        void BoardCalc_Loaded(object sender, RoutedEventArgs e)
        {
            Boards = Math.Floor(LengthRequired / 16);
            BoardsRequired2 = Math.Floor(LengthRequired / 16);
        }

        public Double LengthRequired { get; set; }

        private Double _Boards;
        public Double Boards
        {
            get
            {
                return _Boards;
            }
            set
            {
                _Boards = value;
            }
        }


        //public Double Boards
        //{
        //    get { return (Double)GetValue(BoardsProperty); }
        //    set { SetValue(BoardsProperty, value); }
        //}

        //// Using a DependencyProperty as the backing store for Boards.  This enables animation, styling, binding, etc...
        //public static readonly DependencyProperty BoardsProperty =
        //    DependencyProperty.Register("Boards", typeof(Double), typeof(BoardCalc), null);

        public Double BoardsRequired2
        {
            get { return (Double)GetValue(BoardsRequired2Property); }
            set { SetValue(BoardsRequired2Property, value); }
        }

        // Using a DependencyProperty as the backing store for BoardsRequired2.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty BoardsRequired2Property =
            DependencyProperty.Register("BoardsRequired2", typeof(Double), typeof(BoardCalc), null);



    }

我这样做:

 <StackPanel xmlns:Boards="clr-namespace:BoardsUtil" >
             <Boards:BoardCalc x:Name="boardCalc1"
                LengthRequired="5280"  />

             <TextBlock Text="{Binding ElementName=boardCalc1, Path=Boards}" />

             <TextBlock Text="{Binding ElementName=boardCalc1, Path=BoardsRequired2}" />

         </StackPanel>

两部分问题:

  1. 当我使用依赖项 属性 时,Boards 值将在设计器中计算并显示 330 个板。如果我使用常规 属性 它在设计时将为 0。在运行时,任何一个都可以工作。这是我们期待的吗?如果是这样,或者如果不是,有人可以向我解释为什么会这样,这样我就可以解决它并检查我的其余代码是否真的有效。

  2. 我应该为 LengthRequired 使用依赖项 属性 吗?如果你从 XAML 设置一个 属性,你应该使用依赖关系是吗?但是,如果您只是从 XAML 绑定到 属性,您可以使用常规的 属性?这是我们在这里看到的行为吗?这是我们期待的吗?不?是的?为什么,这样我就可以决定要做什么了。

Boards value will be calculated at in the designer

引用MSDN(Dependency Property Overview)

The purpose of dependency properties is to provide a way to compute the value of a property based on the value of other inputs.

设计模式不是运行时模式,设计人员使用依赖属性,因为它专门反映它们。设计器没有订阅 INotifyPropertyChanged,也没有像依赖属性那样与普通属性交互。

Should I be using a dependency property for LengthRequired?

我会对其进行通知 属性 更改,但除非您正在创建自定义控件,否则使用依赖项 属性 是多余的。

If you set a property from XAML, you should use dependency yes

不,可以绑定(设置)到 XAML 中的任何 属性,因为它只是反射。绑定通过提供的 route(路径信息)反映数据上下文中的项目。

但是绑定行为不同于在绑定 之后发生的获取数据的行为。

But if you merely BIND to a property from XAML you can use a regular property?

是的,但在大多数情况下使用 INotifyPropertyChanged 操作来帮助绑定和检索数据。


使用这些基本规则

  • 在控件上使用依赖属性,因为它们在控件使用者的设计模式下是可识别的。否则用户需要找到属性,不能设置XAML中的值;不像依赖项 属性.
  • 任何 属性 都可以绑定,但发生的更改可能不会 电报 到它绑定的任何东西...以提供该过程的良好数据, 使用 INotifyPropertyChanged 操作。

使用依赖属性的主要原因是允许底层子系统提供额外的基于 UI/XAML/WPF 的功能,即:

1) 绑定。 在这段代码中:

<Slider x:Name="slid1" Maximum="5280" Minimum="16" Value="250" />
<Boards:BoardCalc x:Name="boardCalc1"
            LengthRequired="{Binding ElementName=slid1,Path=Value"  />

LengthRequired 必须是依赖项 属性。您可以像这样设置 LengthRequired

LengthRequired = "5280"

你可以做到这一点

Text={Binding ElementName=boardCalc1, Path=LengthRequired} ...

但您不能使用绑定扩展 SET LengthRequired。

2) 动画 3) 造型

基本原理相同。要允许底层 UI 子系统从 0 到 100 或其他任何动画,或者让子系统选择样式和主题等等,它必须是一个依赖项 属性.

1,2,3。使用依赖项的原因 属性。 对于常规属性,您可以插入 INotify。