WPF数据绑定对象Binding中的辅助属性

数据绑定方向——Model

namespace System.Windows.Data
{
    public enum BindingMode
    {
        TwoWay = 0,
        OneWay = 1,
        OneTime = 2,
        OneWayToSource = 3,
        Default = 4
    }
}

TwoWay = 0,

绑定的双方,值可以相互传递

OneWay = 1,

绑定后,数据从源到目标  Data.Value->TextBox.Text

OneTime = 2,

绑定的双向,在初始化的时候,数据同步一次,Data.Value->TextBox.Text

OneWayToSource = 3,

绑定后,数据从目标到源,TextBox.Text->Data.Value

Default = 4

默认,没有写Model属性的时候是这个值,目标依赖属性的什么形式就是什么形式

    public class Data
    {
        public string Value { get; set; } = "123";
    }
        <TabItem Header="关于Mode属性">
            <StackPanel>
                <!--==================关于Mode属性=========================-->
                <!--TextBlock的Text属性默认是单向绑定,TextBox的Text属性默认是双向绑定-->
                <TextBlock Text="{Binding Value}"/>
                <!--原因是:上面对象是只是做显示,下面对象可以做编辑(页面输入时,信息会回写,写到Value属性里去)-->
                <!--这里问题与Value的属性类型无关-->
                <TextBox Text="{Binding Value,Mode=TwoWay}"/>
                <TextBox Text="{Binding Value,Mode=OneTime}"/>
                <TextBox Text="{Binding Value,Mode=OneWayToSource}"/>
                <TextBox/>
            </StackPanel>
        </TabItem>

更新数据源时机——UpdateSourceTrigger

namespace System.Windows.Data
{
    public enum UpdateSourceTrigger
    {
        Default = 0,
        PropertyChanged = 1,
        LostFocus = 2,
        Explicit = 3
    }
}

Default = 0,

不更新源

PropertyChanged = 1,

属性值发生变化的时候,更新源

LostFocus = 2,

失去焦点,更新源

Explicit = 3

明确的告诉进行更新

        <TabItem Header="关于UpdateSourceTrigger属性">
            <StackPanel>
                <!--==============关于UpdateSourceTrigger属性==============-->
                <!--TextBox的Text属性推送给源的时机是控件失去焦点-->
                <Button Content="Button" Click="Button_Click"/>
                <TextBox Text="{Binding Value,Mode=TwoWay}"/>
                <TextBox Text="{Binding Value,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
                <TextBox Text="{Binding Value,Mode=TwoWay,UpdateSourceTrigger=Explicit}" Name="tb"/>
            </StackPanel>
        </TabItem>
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            // 获取对应控件属性的绑定表达式
            BindingExpression bindingExpression = tb.GetBindingExpression(TextBox.TextProperty);
            // 指定更新源
            bindingExpression.UpdateSource();
        }

延时更新数据源——Delay

        <TabItem Header="关于Delay属性">
            <!--
                // 变化的时候做什么逻辑
                // UpdateSrouce的时候,每次变化都会触发Set,如果Set里有逻辑   跟不上,
                // 希望每次输入都能直接触发更新,不需要失去焦点,不希望每个字符都更新
                // 可以让更新的时机稍等下  Delay
                // Text属性被连续更新后多少毫秒
            -->
            <StackPanel>
                <!--这里更新的时机是失去焦点,Delay无效,不会等待2000-->
                <TextBox Text="{Binding Value,Mode=TwoWay,Delay=2000}"/>
                <!--实时同步更新源的时候,可以等待-->
                <TextBox Text="{Binding Value,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged,Delay=2000}"/>
                <TextBox/>
            </StackPanel>
        </TabItem>

数据显示格式——StringFormat

        <TabItem Header="StringFormat">
            <StackPanel>
                <TextBlock Text="{Binding IntValue,StringFormat={}{0:000000}}"/>
                <TextBlock Text="{Binding IntValue,StringFormat={}{0:P2}}"/>
                <TextBlock Text="{Binding FloatValue,StringFormat={}{0:0.000}}"/>
                <TextBlock Text="{Binding FloatValue,StringFormat={}{0:N3}}"/>
                <TextBlock Text="{Binding FloatValue,StringFormat={}{0:C3},ConverterCulture=zh-cn}"/>
                <TextBlock Text="{Binding DateTimeValue,StringFormat={}{0:yyyy-MM-dd}}"/>
                <Border Height="1" Background="Red"/>
                <TextBlock Text="{Binding IntValue,StringFormat=\{0:000000\}}"/>
                <TextBlock Text="{Binding IntValue,StringFormat=\{0:P2\}}"/>
            </StackPanel>
        </TabItem>

触发器——Converter

使用自定义触发器转义字符

    public class Data
    {
        public string Value { get; set; } = "123";

        public int IntValue { get; set; } = 100;

        public float FloatValue { get; set; } = 0.1f;

        public DateTime DateTimeValue { get; set; } = DateTime.Now;

        public int CodeValue { get; set; } = 64;  // '@'

        public Data()
        {
            //IntValue.ToString("000000.00");
            //DateTimeValue.ToString("yyyy-MM-dd HH:mm:ss");
        }
    }
    // MarupExtension这个基类不是必须继承,主要目标是希望CharConverter可以以{}的形式在XAML中实例化
    // 比如:<TextBlock Text="{Binding CodeValue,Converter={local:CharConverter}}"/>
    // 没有继承MarkupExtensionn的情况下,XAML中以资源或标签对象的方式进行引用
    // 比如:<TextBlock Text="{Binding CodeValue,Converter={StaticResource cc}}"/>
    public class CharConverter :MarkupExtension, IValueConverter
    {
        // 数据从源到目标的时候,执行这个方法,将这个方法的结果显示在目标
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            //int.Parse(value.ToString()) * 0.1;
            // &#@e618  
            // (char)e618   ' '
            // 源的数据    64   int     
            return (char)int.Parse(value.ToString());
        }

        // 数据从目标到源的时候。执行这个方法,将这个方法的结果提交给源
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            // 目标的数据   a    97 
            //value
            return (int)(value.ToString()[0]);
        }

        public override object ProvideValue(IServiceProvider serviceProvider)
        {
            return this;
        }
    }
    <Window.Resources>
        <local:CharConverter x:Key="cc"/>
    </Window.Resources>
        <TabItem Header="Converter">
            <StackPanel>
                <!--这种方式需要CharConverter实现MarkupExtension基类-->
                <TextBlock Text="{Binding CodeValue,Converter={local:CharConverter}}"/>
                <!--这种方式需要提前定义资源-->
                <TextBlock Text="{Binding CodeValue,Converter={StaticResource cc}}"/>
                <!--这种方式 可以不用定义资源-->
                <TextBlock>
                    <TextBlock.Text>
                        <Binding Path="CodeValue">
                            <Binding.Converter>
                                <local:CharConverter/>
                            </Binding.Converter>
                        </Binding>
                    </TextBlock.Text>
                </TextBlock>

                <TextBox Text="{Binding CodeValue,Converter={StaticResource cc},UpdateSourceTrigger=PropertyChanged}"
                         TextChanged="TextBox_TextChanged">
                </TextBox>
            </StackPanel>
        </TabItem>

使用系统默认触发器转换控件属性

    <Window.Resources>
        <!--自定义转换器-->
        <local:CharConverter x:Key="cc"/>

        <!--系统默认的转换器,非常常用-->
        <BooleanToVisibilityConverter x:Key="btv"/>

        <!--主要针对GroupBox的边框处理,不常用-->
        <BorderGapMaskConverter x:Key="bgmc"/>
    </Window.Resources>
                <CheckBox Content="展开" VerticalContentAlignment="Center" IsChecked="{x:Null}"
                          Name="cb"/>
                <Border Height="30" Background="Orange" 
                        Visibility="{Binding ElementName=cb,Path=IsChecked,Converter={StaticResource btv}}"/>

<Window.Resources>
        <AlternationConverter x:Key="ac">
            <SolidColorBrush>red</SolidColorBrush>
            <SolidColorBrush>Green</SolidColorBrush>
            <SolidColorBrush>orange</SolidColorBrush>
        </AlternationConverter>

        <x:Array Type="sys:Int32" x:Key="adatas">
            <sys:Int32>1</sys:Int32>
            <sys:Int32>2</sys:Int32>
            <sys:Int32>3</sys:Int32>
            <sys:Int32>4</sys:Int32>
            <sys:Int32>5</sys:Int32>
        </x:Array>
        <Style TargetType="ListBoxItem">
            <Setter Property="Background" 
                    Value="{Binding RelativeSource={RelativeSource Self},Path=(ItemsControl.AlternationIndex),Converter={StaticResource ac}}"/>
        </Style>
    </Window.Resources>
                <ListBox ItemsSource="{StaticResource adatas}" AlternationCount="3">

触发器参数传递——ConverterParameter

        // 1:男   2:女
        public int Gender { get; set; } = 2;
// MarupExtension这个基类不是必须继承,主要目标是希望CharConverter可以以{}的形式在XAML中实例化
    // 比如:<TextBlock Text="{Binding CodeValue,Converter={local:CharConverter}}"/>
    // 没有继承MarkupExtensionn的情况下,XAML中以资源或标签对象的方式进行引用
    // 比如:<TextBlock Text="{Binding CodeValue,Converter={StaticResource cc}}"/>
    public class CharConverter : MarkupExtension, IValueConverter
    {
        // 数据从源到目标的时候,执行这个方法,将这个方法的结果显示在目标
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            //int.Parse(value.ToString()) * 0.1;
            // &#@e618  
            // (char)e618   ' '
            // 源的数据    64   int     
            int p = parameter == null ? 0 : int.Parse(parameter.ToString());
            return (char)(int.Parse(value.ToString()) + p);
        }

        // 数据从目标到源的时候。执行这个方法,将这个方法的结果提交给源
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            // 目标的数据   a    97 
            //value
            return (int)(value.ToString()[0]);
        }

        public override object ProvideValue(IServiceProvider serviceProvider)
        {
            return this;
        }
    }
    public class GenderConverter : IValueConverter
    {
        // 源 到 目标(IsChecked   bool)
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            //value是源的属性值 
            var v = int.Parse(value.ToString());
            var p = int.Parse(parameter.ToString());
            if (v == p) return true;

            return false;
        }

        // 目标到 源
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            //value是目标的属性值
            if (Boolean.Parse(value.ToString()))
                return parameter;

            return null;
        }
    }
    <Window.Resources>
        <!--自定义转换器-->
        <local:CharConverter x:Key="cc"/>
        <local:GenderConverter x:Key="gc"/>
    </Window.Resources>
                <!--ConverterParameter可以参定参数参与到转换器逻辑中,但是不允许绑定动态值-->
                <TextBlock Text="{Binding CodeValue,Converter={StaticResource cc},ConverterParameter=0}"/>
                <TextBlock Text="{Binding CodeValue,Converter={StaticResource cc},ConverterParameter=2}"/>
                <TextBlock Text="{Binding CodeValue,Converter={StaticResource cc},ConverterParameter=4}"/>


                <!--小案例:用户编辑窗口,里面有个属性叫性别(可以下拉,RadioButton单选,选项是4个以内用单选)-->
                <!--如何区分这两个信息-》数据中的一个属性中-->
                <RadioButton Content="男" VerticalContentAlignment="Center" 
                             IsChecked="{Binding Gender,Converter={StaticResource gc},ConverterParameter=1}"/>
                <RadioButton Content="女" VerticalContentAlignment="Center" 
                             IsChecked="{Binding Gender,Converter={StaticResource gc},ConverterParameter=2}"/>

绑定异常处理——FallbackValue-TargetNullValue

FallbackValue:无法绑定的时候,显示一个默认值

TargetNullValue:数据源属性的值为Null的时候目标属性中需要显示的信息

    public class MyBinding : Binding
    {
        public MyBinding()
        {
            this.TargetNullValue = "AAAA";
        }
    }
        <TabItem Header="FallbackValue-TargetNullValue">
            <StackPanel>
                <!--绑定失败的表示意思是:1、打不到数据源  2、Path路径无效    以上情况FallbackValue的指定值可以呈现-->
                <TextBlock Text="{Binding ElementName=cb,Path=aaa,FallbackValue=绑定失败}"/>
                <TextBlock Text="{Binding ElementName=cb,Path=IsChecked,FallbackValue=绑定失败,TargetNullValue=空值}"/>
                <TextBlock Text="{local:MyBinding ElementName=cb,Path=IsChecked}"/>
            </StackPanel>
        </TabItem>

数据验证——ValidationRules

系统验证-ExceptionValidationRule

    public class Data : INotifyPropertyChanged
    {
        private int _value;

        public event PropertyChangedEventHandler? PropertyChanged;

        public int Value
        {
            get { return _value; }
            set
            {
                if (value == 123)
                    throw new Exception("比如不能输入123");

                _value = value;
            }
        }
    }
    <Window.DataContext>
        <local:Data/>
    </Window.DataContext>
    <StackPanel Margin="20">
        <TextBox Text="{Binding Value,UpdateSourceTrigger=PropertyChanged}" Name="tb1"/>
        <TextBox TabIndex="0" Focusable="True" Name="tb2">
            <TextBox.Text>
                <Binding Path="Value" UpdateSourceTrigger="PropertyChanged">
                    <Binding.ValidationRules>
                        <ExceptionValidationRule/>
                    </Binding.ValidationRules>
                </Binding>
            </TextBox.Text>
        </TextBox>
        <Button Content="Get exception" Click="Button_Click"/>
        <TextBlock Text="{Binding Path=(Validation.Errors)[0].ErrorContent,ElementName=tb2}" Foreground="Red"/>
    </StackPanel>

目标到源自定义验证-ValidationRule

    public class ValueValidationRule : ValidationRule
    {
        // 实例的调用时机:是在界面上控件被绑定的属性发生变化的时候
        // 从目标到源过程,做这个处理
        // 关于从源中赋值更新的异常提示:IDataErrorInfo
        public override ValidationResult Validate(object value, CultureInfo cultureInfo)
        {
            // 做值的校验规则

            //value参数指的是目标值 

            if (int.TryParse(value.ToString(), out int v))
            {
                if (v == 123)
                    return new ValidationResult(false, "比如不能输入123");
            }
            else
                return new ValidationResult(false, "输入信息不对");

            return new ValidationResult(true, string.Empty);
        }
    }
    <StackPanel Margin="20">
        <TextBox Text="{Binding Value,UpdateSourceTrigger=PropertyChanged}" Name="tb1"/>
        <TextBox TabIndex="0" Focusable="True" Name="tb2">
            <TextBox.Text>
                <Binding Path="Value" UpdateSourceTrigger="PropertyChanged">
                    <Binding.ValidationRules>
                        <ExceptionValidationRule/>
                    </Binding.ValidationRules>
                </Binding>
            </TextBox.Text>
        </TextBox>
        <Button Content="Get exception" Click="Button_Click"/>
        <TextBlock Text="{Binding Path=(Validation.Errors)[0].ErrorContent,ElementName=tb3}" Foreground="Red"/>

        <TextBox TabIndex="0" Focusable="True" Name="tb3">
            <TextBox.Text>
                <Binding Path="Value" UpdateSourceTrigger="PropertyChanged">
                    <Binding.ValidationRules>
                        <local:ValueValidationRule/>
                    </Binding.ValidationRules>
                </Binding>
            </TextBox.Text>
        </TextBox>
    </StackPanel>

源到目标自定义验证-IDataErrorInfo

    public class Data :  INotifyPropertyChanged, IDataErrorInfo
    {
        public event PropertyChangedEventHandler? PropertyChanged;

        private int _value;
        public int Value
        {
            get { return _value; }
            set { _value = value;}
        }

        // 索引
        public string this[string propName]
        {
            get
            {
                if (propName == "Value")
                {
                    if (this.Value > 1000)
                        return "大于1000![IDataErrorInfo]";
                }
                return "";
            }
        }
    }
<TextBox Text="{Binding Value,UpdateSourceTrigger=PropertyChanged,ValidatesOnDataErrors=True}" Name="tb4"/>

 ValidatesOnDataErrors验证开关,不设置此属性为True则不进行校验。

利用特性值进行验证

public class Data : DataBase, INotifyPropertyChanged, IDataErrorInfo
    {
        private int _value;
        [Required]
        [DisplayName("温度报警值")]
        public int Value
        {
            get { return _value; }
            set
            {
                //if (value == 123)
                //    throw new Exception("比如不能输入123");

                _value = value;
            }
        }
        [MaxLength(20)]
        public string MyProperty { get; set; }

        [MaxLength(20)]
        public string MyProperty1 { get; set; }

        [StringLength(maximumLength: 10, MinimumLength = 1)]
        [EmailAddress(ErrorMessage = "邮箱地址不合法")]
        public string Error { get; set; }
        
        
        public string this[string propName]
        {
            get
            {
                //if (propName == "Value")
                //{
                //    if (this.Value > 1000)
                //        return "大于1000![IDataErrorInfo]";
                //}
                //else if (propName == "MyProperty")
                //{
                //    if (this.MyProperty.Length > 50)
                //        return "长度大于50";
                //}

                PropertyInfo pi = this.GetType().GetProperty(propName);

                // IsDefined   检查当前属性是否添加了指定的特定
                if (pi.IsDefined(typeof(MaxLengthAttribute)))
                {
                    // 获取当前属性上指定的特定实例,一般是需要获取特性实例中的某些值的时候使用
                    MaxLengthAttribute ma = (MaxLengthAttribute)pi.GetCustomAttribute(typeof(MaxLengthAttribute));

                    string value = pi.GetValue(this).ToString();
                    if (value.Length > ma.Length)
                        return $"长度大于{ma.Length}";

                }
                if (pi.IsDefined(typeof(RequiredAttribute)))
                {
                    //DisplayNameAttribute da = pi.GetCustomAttribute<DisplayNameAttribute>();
                    //var dn = da.DisplayName;

                    string value = pi.GetValue(this).ToString();
                    if (string.IsNullOrEmpty(value) || value == "0")
                        return $"必然输入{propName}";
                }
                if (pi.IsDefined(typeof(EmailAddressAttribute)))
                {
                    EmailAddressAttribute ea = pi.GetCustomAttribute<EmailAddressAttribute>();
                    if (!ea.IsValid(pi.GetValue(this)))
                        return ea.ErrorMessage;
                }
                return "";
            }
        }
    }

自定义特性验证-IP格式验证

Attribute-基础特性

ValidationAttribute-微软提供所有验证属性的基类,继承Attribute

//public class CheckRepeatAttribute : Attribute
    //{

    //}
    public class IPCheckAttribute : ValidationAttribute
    {
        public override bool IsValid(object? value)
        {
            // 检查IP格式
            // 正则表达式
            // 核心   字符串中每个字符逐个判断

            // 192.168.1.2
            // 使用.间隔
            // 每个间隔的数字都是0-255
            // \.   \d

            string pattern = @"^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$";
            //"^(([0-9]|[1-9][0-9]|1[0-9][0-9]2[0-4][0-9]25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]2[0-4][0-9]25[0-5])"
            //"^((\d\[1-9]\d\1\d\d2([0-4]\d5[0-5]))\.){4}$"
            // \w \W     \s  \S   \d  \D
            // *   +   ?   {10}

            // 工艺编号  asdawd-20324-sdfse3
            // @"^\w{6}\-\w{5}\-\w{6}$"    正则表达式

            if (value == null || string.IsNullOrEmpty(value.ToString())) return true;
            return Regex.IsMatch(value.ToString(), pattern);
        }
    }
public class Data : DataBase, INotifyPropertyChanged, IDataErrorInfo
    {
        [IPCheck(ErrorMessage = "IP格式不正确")]
        [MaxLength(20)]
        public string MyProperty { get; set; }
        
        public string this[string propName]
        {
            get
            {
                if (pi.IsDefined(typeof(IPCheckAttribute)))
                {
                    IPCheckAttribute ca = pi.GetCustomAttribute<IPCheckAttribute>();
                    if (!ca.IsValid(pi.GetValue(this)))
                    {
                        return ca.ErrorMessage;
                    }
                }
                return "";
            }
        }
    }

 样式模板分享

    <Window.Resources>
        <Style TargetType="TextBox">
            <Setter Property="Margin" Value="3"/>
            <!--错误时不显示外框-->
            <Setter Property="Validation.ErrorTemplate">
                <Setter.Value>
                    <ControlTemplate>
                        <AdornedElementPlaceholder/>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="TextBox">
                        <Grid>
                            <Grid.RowDefinitions>
                                <RowDefinition/>
                                <RowDefinition Height="auto"/>
                            </Grid.RowDefinitions>
                            <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"
                                Background="{TemplateBinding Background}"
                                 CornerRadius="5">
                                <ScrollViewer Name="PART_ContentHost" VerticalScrollBarVisibility="Hidden"/>
                            </Border>
                            <!--数据源默认为Window的数据源,需要使用RelativeSource设置数据源为使用该模板的控件本身-->
                            <TextBlock Text="{Binding Path=(Validation.Errors)[0].ErrorContent,RelativeSource={RelativeSource Mode=TemplatedParent}}" Foreground="Red"
                                           Visibility="Collapsed" Name="error"
                                           Grid.Row="1"/>
                        </Grid>
                        <ControlTemplate.Triggers>
                            <Trigger Property="Validation.HasError" Value="True">
                                <Setter TargetName="error" Property="Visibility" Value="Visible"/>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Window.Resources>

多重绑定——MultiBinding

StringFormat

设置StringFormat属性指定显示格式

<Window.DataContext>
        <local:Data/>
    </Window.DataContext>
    <Window.Resources>
        <local:CombinValueConverter x:Key="cvc"/>
        <local:WidthValueConverter x:Key="wvc"/>
    </Window.Resources>
    <StackPanel>
        <StackPanel Orientation="Horizontal">
            <TextBlock Text="{Binding Value}"/>
            <TextBlock Text="{Binding Value2}"/>
        </StackPanel>
        
        <TextBlock>
            <TextBlock.Text>
                <MultiBinding StringFormat="----{1}----{0}">
                    <Binding Path="Value2"/>
                    <Binding Path="Value"/>
                </MultiBinding>
            </TextBlock.Text>
        </TextBlock>
    </StackPanel>

 

Converter

利用转换器进行处理

    public class CombinValueConverter : IMultiValueConverter
    {
        // 数据源到目标的处理过程
        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            return values[1].ToString() + ";" + values[0].ToString();
        }

        // 从显示目标控件属性到数据源的过程
        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
        {
            string[] str = value.ToString().Split(";");

            object[] result = new object[str.Length];
            result[0] = str[0];
            result[1] = int.Parse(str[1].ToString());
            //return new object[] { "AAA", 789 };
            return result;
        }
    }
        <TextBlock>
            <TextBlock.Text>
                <MultiBinding Converter="{StaticResource cvc}">
                    <Binding Path="Value2"/>
                    <Binding Path="Value"/>
                </MultiBinding>
            </TextBlock.Text>
        </TextBlock>

样例分享

绑定一个百分比参数的进度条,需要跟随窗体大小自适应改变

    public class WidthValueConverter : IMultiValueConverter
    {
        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            return double.Parse(values[0].ToString()) * double.Parse(values[1].ToString());
        }

        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
        {
            return null;
        }
    }
        <Border Height="20" Background="Gray" Margin="30,10" Name="bor">
            <Border Background="Orange" HorizontalAlignment="Left">
                <Border.Width>
                    <MultiBinding Converter="{StaticResource wvc}">
                        <Binding Path="ProgressValue"/>
                        <Binding ElementName="bor" Path="ActualWidth"/>
                    </MultiBinding>
                </Border.Width>
            </Border>
        </Border>

优先级绑定——PriorityBinding

IsAsync="True"异步

 Value1延时3秒,Value2延时2秒,Value3延时1秒

 TextBlock显示顺序为Value3-Value2。先显示Value3是因为Value2未到,不显示Value1因为Value2的优先级比Value1高。

<TextBlock>
            <TextBlock.Text>
                <PriorityBinding>
                    <Binding Path="Value2" IsAsync="True"/>
                    <!--2000-->
                    <Binding Path="Value1" IsAsync="True"/>
                    <!--3000-->
                    <Binding Path="Value3" IsAsync="True"/>
                    <!--1000-->
                </PriorityBinding>
            </TextBlock.Text>
        </TextBlock>

 移除绑定——BindingOperations

            //清除TextBox所有的绑定关系
            BindingOperations.ClearAllBindings(this.tb);
            //清除TextBox指定属性的绑定
            BindingOperations.ClearBinding(this.tb, TextBox.TextProperty);

 

posted @ 2023-11-28 11:41  ZHIZRL  阅读(473)  评论(0编辑  收藏  举报