zoukankan      html  css  js  c++  java
  • 一个通用的WPF值转换器

    在WPF中应用数据绑定时经常需要做一些简单的逻辑判断。

    比如ViewModel中有一个HasError(布尔值)的属性表示是否有错误。我需要将它绑定于Button的IsEnable属性上,即:当没有错误时Button可用。这时就需要将HasError取反。WPF默认的绑定引擎是不支持的。

    还有一种情况比如ViewModel中有一个Sex(int值)的属性表示性别,我需要将它绑定到TextBlock上,当值为1时显示男,值为2时显示女。WPF默认绑定也是不支持这种判断的。

    于是一个通用的值转换器就诞生了,用法如下:

    <Button IsEnabled="{Binding HasError, Converter={StaticResource GenericTypeConverter}, ConverterParameter='IsReverse=True'}">OK</Button>

    IsReverse参数表示是否取返,如果转换的值为true则变为false,反之亦然。

    <TextBlock Text="{Binding Sex, Converter={StaticResource GenericTypeConverter}, ConverterParameter='Alias=1:男|2:女|other:未知'}" />

    Alias参数表示将值映射为字符串,other表示当遇到没有指定的值时显示的文本

    另外bool to Visibility的转换可以自动进行,不需要指定参数。

    有意见欢迎指正

    完整代码如下:

    View Code
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows.Data;
    using System.Windows;

    namespace MoodSunshiny.WPF.Converter
    {
        /// <summary>
        
    /// 一个通用的类型转换器,可以提供更多转换控制参数
        
    /// </summary>
        public class GenericTypeConverter : IValueConverter
        {
            /// <summary>
            
    /// 是否反转转换源参数值
            
    /// 仅对bool类型的值有效
            
    /// </summary>
            private bool IsReverse { getset; }

            /// <summary>
            
    /// 用于将转换结果映射为其它字符串
            
    /// 例如:Alias=True:是|False:否
            
    /// </summary>
            private Dictionary<objectstring> Alias { getset; }
            
            /// <summary>
            
    /// 解析转换参数
            
    /// </summary>
            private void AnalyseConvertParameter(string convertParameter)
            {
                /*设置参数默认值*/
                IsReverse = false;
                Alias = null;

                if (!string.IsNullOrEmpty(convertParameter))
                {
                    var pkvs = convertParameter.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                    foreach (var pkv in pkvs)
                    {
                        var pkvo = pkv.Split(new char[] { '=' }, StringSplitOptions.RemoveEmptyEntries);
                        if (pkvo.Length != 2)
                            throw new NotSupportedException("不支持设置:" + pkv);
                        var pk = pkvo[0].Trim();
                        var pv = pkvo[1].Trim();

                        switch (pk)
                        {
                            case "IsReverse":
                                bool b;
                                if (!bool.TryParse(pv, out b))
                                    throw new NotSupportedException("参数取值错误:" + pkv);
                                else
                                    IsReverse = b;
                                break;
                            case "Alias":
                                {
                                    Alias = new Dictionary<objectstring>();
                                    var dfkvs = pv.Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
                                    foreach (var dfkv in dfkvs)
                                    {
                                        var dfkvo = dfkv.Split(new char[] { ':' }, StringSplitOptions.RemoveEmptyEntries);
                                        if (dfkvo.Length != 2)
                                            throw new NotSupportedException("不支持设置:" + dfkvo);
                                        var dfk = dfkvo[0].Trim();
                                        var dfv = dfkvo[1].Trim();

                                        object oKey = null;
                                        int i;
                                        if (dfk.Equals("true", StringComparison.OrdinalIgnoreCase))
                                            oKey = true;
                                        else if (dfk.Equals("false", StringComparison.OrdinalIgnoreCase))
                                            oKey = false;
                                        else if (dfk.Equals("other", StringComparison.OrdinalIgnoreCase))
                                            oKey = "other";
                                        else if (int.TryParse(dfk, out i))
                                            oKey = i;
                                        else
                                            throw new NotSupportedException("参数取值错误:" + dfkv);

                                        Alias[oKey] = dfv;
                                    }
                                }
                                break;
                            default:
                                throw new NotSupportedException("不支持的参数名:" + pk);
                        }
                    }
                }
            }

            public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
            {
                AnalyseConvertParameter(parameter as string);

                try
                {
                    var sourceType = value.GetType();
                    if (IsReverse && sourceType == typeof(bool))
                        value = !((bool)value);

                    if (targetType == typeof(string))
                    {
                        if (Alias != null && Alias.ContainsKey(value))
                            return Alias[value];
                        else if (Alias != null && Alias.ContainsKey("other"))
                            return Alias["other"];
                        else
                            return  value == null ? "" : value.ToString();
                    }
                    if (targetType == typeof(bool))
                    {
                        if (sourceType == typeof(Visibility))
                            return (Visibility)value == Visibility.Visible;
                    }
                    else if (targetType.IsEnum)
                    {
                        if (sourceType == typeof(bool) && targetType == typeof(Visibility))
                        {
                            return (bool)value ? Visibility.Visible : Visibility.Collapsed;
                        }
                        else
                        {
                            return Enum.Parse(targetType, value.ToString(), true);
                        }
                    }
                    else
                    {
                        return System.Convert.ChangeType(value, targetType);
                    }

                    return System.Convert.ChangeType(value, targetType);
                }
                catch
                {
                    return null;
                }
            }

            public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
            {
                return Convert(value, targetType, parameter, culture);
            }
        }
    }
  • 相关阅读:
    jQuery的end() 方法
    jQuery.extend 函数使用详解
    AutoMapper完成Dto与Model的转换
    IoC实践--用Unity实现MVC5.0的IoC控制反转方法
    IoC实践--用Autofac实现MVC5.0的IoC控制反转方法
    Unity依赖注入使用详解
    React+BootStrap+ASP.NET MVC实现自适应和组件的复用
    oracle基础开发工具及常用命令
    Cisco配置发送日志到日志服务器
    Redis讲解
  • 原文地址:https://www.cnblogs.com/mondol/p/2482723.html
Copyright © 2011-2022 走看看