• WPF 属性值绑定、转换


    TextBlock绑定属性

    绑定集合中的第一项的属性

    <TextBlock Text="{Binding [1].PropertyName1}" DataContext="{Binding DemoList}"/>
    

    绑定单个属性及转换器

    <UserControl.Resources>
        <cvt:StateConv x:Key="stateConv"/>
    </UserControl.Resources>
    ...
    <TextBlock Text="{Binding Name, StringFormat={}{0:F2}, Converter="{StaticResource stateConv}"}"/>
    
    using System;
    using System.Globalization;
    using System.Windows;
    using System.Windows.Data;
    public class StateConv: IValueConverter
    {
        // 此文本将显示在控件中(比如:TextBox)
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            int type = 0;
            if (int.TryParse(value.ToString(), out type))
            {
                if (type == 1) { return "正常"; }
                else { return "异常"; }   
            } 
            return DependencyProperty.UnsetValue;                          
        }
        // 目标数据格式转换为原数据格式(正常->1)
        // 当您更改控件TextBox的值时,ConvertBack方法将在绑定再次触发时调用(默认OnFocusLost)
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (string.IsNullOrEmpty(value?.ToString()))
                    return -1;
                
            var item = TypeResource.FirstOrDefault(x => x.DisplayText == value.ToString());
            if (item == null)
            {
               return -1;
            }
            return item.Key;
        }
    }
    

    转换器2

    数值转换,显示指定枚举类型的文本描述

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value != null && int.TryParse(value.ToString(), out int type))
        {
            if (Enum.IsDefined(typeof(PropertyNameEnumType), type))
            {
                var @enum = (PropertyNameEnumType)type;
                return @enum.GetEnumDescription();
            }
        }
        return "未知状态";
    }
    

    多重绑定1

    <Label.Content>
        <TextBlock>
    	<TextBlock.Text>
    		<MultiBinding StringFormat="{}{0}({1})">
    			<Binding Path="Name1" TargetNullValue="用默认值来显示为空的字段" />
    			<Binding Path="Name2" />
    		</MultiBinding>
    	</TextBlock.Text>
        </TextBlock>
    </Label.Content>
    

    StringFormat要求它的目标是string类型。 可在指定控件内嵌套TextBlock进行自定义格式转换。
    若要体现动态数据,属性所属类需要实现INotificationPropertyChanged接口,绑定的属性可以响应属性更改事件。

    多重绑定2

    <UserControl.Resources>
        <cvt:MultiStateConv x:Key="multiStateConverter"/>
        <cvt:MultiVersionTypeConv x:Key="multiVersionTypeConverter"/>
    </UserControl.Resources>
    ...
    <TextBlock>
        <TextBlock.Text>
            <MultiBinding Converter="{StaticResource multiStateConverter}" ConverterParameter="{StaticResource bindingProxy}">
                <Binding Path="Name"/>
                <Binding Path="Name2"/>
                <!--绑定父级属性 PropertyName2-->
                <Binding Path="DataContext.PropertyName2" RelativeSource="{RelativeSource AncestorLevel=2, AncestorType={x:Type ListBoxItem}}"/>
            </MultiBinding>
        </TextBlock.Content>
    </TextBlock>
    
    <DataGridTextColumn Header="版本类型" Width="*">
        <DataGridTextColumn.Binding>
            <MultiBinding Converter="{StaticResource multiVersionTypeConverter}" ConverterParameter="{StaticResource multiStateConverter}">
                <Binding Path="Type1"/>
                <Binding Path="Type2"/>
            </MultiBinding>
        </DataGridTextColumn.Binding>
    </DataGridTextColumn>
    
    using System;
    using System.Globalization;
    using System.Windows.Data;
    
    [ValueConversion(typeof(object[]), typeof(string))]
    class MultiStateConv : IMultiValueConverter
    {
        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            var cvt = parameter as MultiStateConv;
            string rslt = string.Empty;
            if (int.TryParse(values[0].ToString(), out int type))
            {
                //...             
            }
            if (int.TryParse(values[1].ToString(), out int type2))
            {
                //...
            }
            return rslt;                           
        }
    
        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
    

    多重绑定3

    当传递的参数过多时,可以使用绑定代理。
    当显示逻辑比较复杂时,有多个参数规则,可重复设置同样内容,并控制不同的显隐来实现。

    xmlns:cvt="clr-namespace:ProjectName.Converters" 
    
    <Color x:Key="Color1">#FF4E5E</Color>
    <SolidColorBrush x:Key="Brush1" Color="{DynamicResource Color1}"/>
    <cvt:BindingProxy x:Key="bindingProxy" Data="{DynamicResource Brush1}" Reserve="{DynamicResource 3thDllBrush}" Thread="10.0"/>
    
    <cvt:ExceptionValueConv x:Key="exceptionValueConveter"/>
    <cvt:ExceptionForegroundVisibleConv x:Key="exceptionForegroundVisibleConveter"/>
    <cvt:ExceptionForegroundReVisibleConv x:Key="exceptionForegroundReVisibleConveter"/>
    
    <Grid>
        <TextBlock Foreground="{DynamicResource Brush3}"
                   Visibility="{Binding Percent, Converter={StaticResource exceptionForegroundVisibleConveter}, ConverterParameter={StaticResource bindingProxy}}">
            <Run Text="{Binding Percent, StringFormat={}{0:f1}, Converter={StaticResource exceptionValueConveter}}" />
            <Run Text="%"/>
        </TextBlock>
        <!--同样内容-->
        <TextBlock Foreground="{DynamicResource Brush4}"
                   Visibility="{Binding Percent, Converter={StaticResource exceptionForegroundReVisibleConveter}, ConverterParameter={StaticResource bindingProxy}}"> 
            <Run Text="{Binding Percent, StringFormat={}{0:f1}, Converter={StaticResource exceptionValueConveter}}" />
            <Run Text="%"/>
        </TextBlock>
    </Grid>
    
    
    
    using System.Windows;
    
    internal class BindingProxy : Freezable
    {
        protected override Freezable CreateInstanceCore()
        {
            return new BindingProxy();
        }
    
        /// <summary>
        /// 原始数据
        /// </summary>
        public object Data
        {
            get { return (object)GetValue(DataProperty); }
            set { SetValue(DataProperty, value); }
        }
        public static readonly DependencyProperty DataProperty = DependencyProperty.Register("Data", typeof(object), typeof(BindingProxy), new PropertyMetadata(null));
    
        /// <summary>
        /// 替代数据
        /// </summary>
        public object Reserve
        {
            get { return (object)GetValue(ReserveProperty); }
            set { SetValue(ReserveProperty, value); }
        }
        public static readonly DependencyProperty ReserveProperty = DependencyProperty.Register("Reserve", typeof(object), typeof(BindingProxy), new PropertyMetadata(null));
    
        /// <summary>
        /// 阈值
        /// </summary>
        public double Thread
        {
            get { return (double)GetValue(ThreadProperty); }
            set { SetValue(ThreadProperty, value); }
        }
        public static readonly DependencyProperty ThreadProperty = DependencyProperty.Register("Thread", typeof(double), typeof(BindingProxy), new PropertyMetadata(0.0));
    }
    

    可直接调用资源词典

    Converter.xaml

    {Binding Converter={StaticResource Boolean2VisibilityConverter}}

    <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                        xmlns:converter="clr-namespace:XXX.Converters">
        <BooleanToVisibilityConverter x:Key="Boolean2VisibilityConverter"/>
        ......
    </ResourceDictionary>
    

    DataGrid中,编辑状态下触发事件

    <DataGridTextColumn  Width="auto" IsReadOnly="False"  MinWidth="110"  Binding="{Binding Name}" Header="名称">
        <DataGridTextColumn.EditingElementStyle>
            <Style TargetType="TextBox">
                <EventSetter Event="TextChanged" Handler="DataGridTextColumn_Name_TextChanged"/>
                <EventSetter Event="LostFocus" Handler="DataGridTextColumn_Name_LostFocus"/>
            </Style>
        </DataGridTextColumn.EditingElementStyle>
    </DataGridTextColumn>
    

    RadioButton绑定属性

    <UserControl.Resources>
        <cvt:RadioCheckConv x:Key="radioCheckConverter"/>
    </UserControl.Resources>
    
    <RadioButton Content="XXX" HorizontalAlignment="Center" GroupName="GroupName1" 
                 IsChecked="{Binding PropertyName1, Converter={StaticResource radioCheckConverter}, ConverterParameter=1}"/>
    

    其中,属性PropertyName1是可通知的;

    using System;
    using System.Windows.Data;
    public class RadioCheckConv : IValueConverter
    {
      public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
      {
          if (value == null || parameter == null)
          {
              return false;
          }
          if (value.ToString().Equals(parameter.ToString()))
          {
              return true;
          }
          return false;
      }
    
      public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
      {
          if (value == null || parameter == null)
          {
              return null;
          }
          if ((bool)value)
          {
              return parameter.ToString();
          }
          return null;
      }
    }
    

    TextBox绑定属性

    <TextBox x:name="txt" Text="{Binding PropertName, Mode=TwoWay, UpdateSourceTrigger=Default}" />

    控件绑定属性时,UpdateSourceTrigger默认为Default。源PropertName不会随着Text属性的改变而立即更新;TextBox中的变化并不是立即传递到源,而是在TextBox失去焦点后,源才更新。

    UpdateSourceTrigger枚举 说明 备注
    Default 默认值 默认为LostFocuse
    Explicit 当应用程序调用 UpdateSource 方法时生效 通过代码手动推送来更新
    LostFocus 失去焦点的时候触发
    PropertyChanged 属性改变的时候触发 源会立即更新
    using System.Windows.Data;
    private void btnUpdateSource_Click(object sender, RoutedEventArgs e)
    {
        // Explicit时,手动更新绑定的属性
        BindingExpression binding = txt.GetBindingExpression(TextBox.TextProperty);
        binding.UpdateSource();
    }
    

    后台绑定

    <cvt:IntToBoolConv x:Key="intToBoolConverter"/>
    <CheckBox Content="启用" x:Name="CheckBox1"
       IsChecked="{Binding IsEnable, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource intToBoolConverter}}" />
    
    this.DataContext = this;  // Prism可省略此步;此时IsEnable可通知客户端即可,不要求是依赖属性propdp
    

    相当于后台实现

    <CheckBox Content="启用" x:Name="CheckBox1"  />
    using System.Windows.Data;
    BindingOperations.SetBinding(CheckBox1,   // 控件名称
        CheckBox.IsCheckedProperty,           // 控件属性
        new Binding                           // 绑定内容
        {
            Path = new PropertyPath("IsEnable"), // 依赖属性 IsEnable
            Mode = BindingMode.TwoWay,
            UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged,
            Converter = new IntToBoolConv(),
            Source = this,                    // 属性所属对象
        });
    
    
  • 相关阅读:
    Houdini 快捷键使用说明
    在Houdini中创建自定义的Python函数
    用正则表达式校验QQ号码
    [Chatter] 看小说「数字风暴」有感
    [.NET] 当用System.Messaging.MessageQueue.Send传送数据遇到InvalidCastException、NullReferenceException
    [Visual Studio] 方案总管中,自定义档案与档案之间的父子关系
    [.NET] 子对象方法的参数,参考子对象型别做为输入型别
    [Chatter] 引用新技术的考虑
    [Architecture Pattern] Inversion of Logging
    [Architecture Design] DI Thread Tips
  • 原文地址:https://www.cnblogs.com/wesson2019-blog/p/12619655.html
Copyright © 2020-2023  润新知