XAML依赖属性与常规属性

时间:2015-06-10 15:02:50

标签: wpf xaml properties dependency-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绑定到一个属性,你可以使用常规属性?这是我们在这里看到的行为吗?这是我们所期望的吗?没有?是?为什么,所以我可以决定该怎么做。

2 个答案:

答案 0 :(得分:4)

使用依赖项属性的主要原因是允许底层子系统提供额外的基于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} ...

但您无法使用Binding扩展程序 SET LengthRequired。

2)动画 3)造型

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

1,2,3。使用依赖属性的原因。 对于常规属性,您可以在INotify中进行阻塞。

答案 1 :(得分:2)

  

Boards值将在设计师

中计算

引用MSDN(Dependency Property Overview

  

依赖属性的目的是提供一种计算方法   基于其他输入值的属性值。

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

  

我应该使用LengthRequired的依赖属性吗?

我会对其进行通知属性更改,但除非您要创建自定义控件,否则使用Dependency属性是过度的。

  

如果从XAML设置属性,则应使用依赖性是

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

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

  

但是,如果你只是从XAML绑定一个属性,你可以使用常规属性吗?

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

使用这些基本规则

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