zoukankan      html  css  js  c++  java
  • 2019-4-12-WPF-绑定的默认模式

    title author date CreateTime categories
    WPF 绑定的默认模式
    lindexi
    2019-04-12 09:38:58 +0800
    2019-04-12 09:37:55 +0800
    WPF

    小伙伴绑定了一个属性,但是发现属性在更新的时候没有同步到后台,他说在 WPF 绑定的默认值是什么?为什么没有设置 Mode 的属性,有的是双向有的是单向?本文就来告诉大家在 WPF 定义的依赖属性是如何控制绑定的是双向还是单向的方法

    在依赖属性或附加属性,都可以在定义的时候传入 FrameworkPropertyMetadata 请看代码

            public static readonly DependencyProperty TwoWayProperty =
                DependencyProperty.Register("TwoWay", typeof(string), typeof(MainWindow), new FrameworkPropertyMetadata(""));

    上面代码的使用和默认不相同,修改 PropertyMetadata 为 FrameworkPropertyMetadata 虽然传入的默认值参数都是一样的,但是 FrameworkPropertyMetadata 可以传入更多的参数,如可以传入 FrameworkPropertyMetadataOptions 变量

    在 FrameworkPropertyMetadataOptions 变量可以通过设置 BindsTwoWayByDefault 指定这个值默认的绑定是双向的

    虽然从 Binding 的 Mode 的枚举的定义是

        public enum BindingMode
        {
            TwoWay,
            OneWay,
            OneTime,
            OneWayToSource,
            Default
        }

    默认的枚举值 0 是 TwoWay 但是在 Mode 属性通过特性设置了默认的值是 Default 而如果设置默认的值是 Default 就会读取绑定的属性的对应的 FrameworkPropertyMetadata 是否有设置默认是双向

            [DefaultValue(BindingMode.Default)]
    

    在 TextBlock 这些控件,有很多属性的绑定都是双向的,但是如果是小伙伴定义的控件,他可以定义出默认是双向绑定的或没有的

          public string TwoWay
            {
                get { return (string) GetValue(TwoWayProperty); }
                set { SetValue(TwoWayProperty, value); }
            }
    
    
            public static readonly DependencyProperty TwoWayProperty =
                DependencyProperty.Register("TwoWay", typeof(string), typeof(MainWindow), new FrameworkPropertyMetadata("", FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
    
            public string OneWay
            {
                get { return (string) GetValue(OneWayProperty); }
                set { SetValue(OneWayProperty, value); }
            }
    
            public static readonly DependencyProperty OneWayProperty =
                DependencyProperty.Register("OneWay", typeof(string), typeof(MainWindow), new FrameworkPropertyMetadata("", FrameworkPropertyMetadataOptions.AffectsArrange));
           

    尝试再定义两个属性,绑定依赖属性

           public string Property1
            {
                get => _property; 
                set
                {
                    _property = value;
                    OnPropertyChanged();
                }
            }
    
            public string Property2
            {
                get => _property2; 
                set
                {
                    _property2 = value;
                    OnPropertyChanged();
                }
            }
    
            private string _property;
            private string _property2;
    
            public event PropertyChangedEventHandler PropertyChanged;
    
            private void OnPropertyChanged([CallerMemberName]string name = "")
            {
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
            }

    在构造函数绑定属性

           public MainWindow()
            {
                DataContext = this;
                InitializeComponent();
    
                Binding binding = new Binding
                {
                    Path = new PropertyPath("Property1"),
                    Mode = BindingMode.Default
                };
    
                BindingOperations.SetBinding(this, TwoWayProperty, binding);
    
                binding = new Binding
                {
                    Path = new PropertyPath("Property2"),
                    Mode = BindingMode.Default
                };
    
                BindingOperations.SetBinding(this, OneWayProperty, binding);
            }

    在界面绑定一下属性就知道属性是否修改

            <StackPanel VerticalAlignment="Center" HorizontalAlignment="Center">
                <TextBlock Margin="10,10,10,10" Text="{Binding Property1}"></TextBlock>
                <TextBlock Text="{Binding Property2}" Margin="10,10,10,10"></TextBlock>
                <TextBlock x:Name="Text" Margin="10,10,10,10"></TextBlock>
                <Button Content="修改值" Click="Button_Click"></Button>
            </StackPanel>

    界面的按钮点击的时候修改属性

            private void Button_Click(object sender, RoutedEventArgs e)
            {
                Random ran = new Random();
                Text.Text = ran.Next().ToString();
                OneWay = Text.Text;
                TwoWay = Text.Text;
            }

    运行代码点击按钮,可以发现只有 Property1 会修改

    所有代码在 github

    建议只有在熟悉的属性才可以不写 Mode 防止翻车

    Explain Binding Mode In WPF

    BindingMode Enum (System.Windows.Data)

    .net - What are the defaults for Binding.Mode=Default for WPF controls? - Stack Overflow

  • 相关阅读:
    ReentrantLock与synchronized的差别
    读TIJ -1 对象入门
    wikioi 2573 大顶堆与小顶堆并用
    开源 免费 java CMS
    UVA10972
    springboot5
    spring-boot4
    spring-boot3
    spring-boot2
    spring-boot1
  • 原文地址:https://www.cnblogs.com/lindexi/p/12086419.html
Copyright © 2011-2022 走看看