• Silverlight渐进学习系列(1)——IValueConverter的使用


    背景

    本文通过一个简单的按钮权限来描述如何使用IValueConverter接口。

    首先可以看到IValueConverter包含两个接口方法:

    object Convert(object value, Type targetType, object parameter, CultureInfo culture);

    以及

    object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture);

    实现了源数据类型以及目标数据类型之间的转换。

     

    详细分析

    1. 该按钮权限分为4种状态:查询,修改,添加,删除;用户的权限可以是4种状态中的任意组合;

    比如3级用户只拥有查询的权限;2级用户拥有查询和修改的权限;超级管理员拥有所有状态的权限;

    UI上的显示很简单,如果有权限,按钮则显示;无权限,按钮就不显示;

     

    2. 有些人考虑这个问题的时候,可能会想到在数据库设计这个权限的时候,会使用字符串形式,如“1”表示拥有查询权限,“1,3”表示拥有查询和添加权限,“1,2,3,4”表示拥有所有权限。而我这里考虑是采用位运算的方式进行处理;考虑到4种状态,我先创建一个用户权限枚举类型

    代码
    /// <summary> 
    /// 用户权限 
    /// </summary> 
    public enum UserRight 

        None 
    = 0

        
    /// <summary> 
        
    /// 查询权限(1) 
        
    /// </summary> 
        Select = 1

        
    /// <summary> 
        
    /// 修改权限(2) 
        
    /// </summary> 
        Update = 2

        
    /// <summary> 
        
    /// 插入权限(3) 
        
    /// </summary> 
        Insert = 3

        
    /// <summary> 
        
    /// 删除权限(4) 
        
    /// </summary> 
        Delete = 4 
    }

     根据4种状态的组合,可以得到15种情况的组合;所以通过1—15整型数值,可以对应每一种的组合情况,这样可以通过一个枚举扩展方法进行实现:

    代码
    /// <summary> 
    /// 将复合权限类型ID 转换成 权限枚举类型数组 
    /// </summary> 
    /// <param name="userRightComplex"></param> 
    /// <returns></returns> 
    public static UserRight[] ToUserRightArray(this int userRightComplex) 

        
    int max = EnumHelper.GetValues(typeof(UserRight)).Length - 2//除去None枚举,并需要再减1,所以减2 

        List
    <UserRight> userRightList = null
        
    while (userRightComplex > 0
        { 
            
    if (userRightList == null
                userRightList 
    = new List<UserRight>(); 

            
    int arg = Convert.ToInt32(Math.Pow(2, max)); 
            
    if (userRightComplex >= arg) 
            { 
                userRightComplex 
    -= arg; 
                userRightList.Add((UserRight)Enum.Parse(
    typeof(UserRight), (max + 1).ToString(), true)); 
            } 
            max
    --
        } 
        
    if (userRightList == null || userRightList.Count == 0
        { 
            
    return null
        } 
        
    return userRightList.ToArray(); 
    }

    这样,通过一个整型值可以得到一个用户权限的数组。

    如1得到一个“查询”数组,5得到一个“查询、添加”数组,15得到所有状态的数组;

    这样做的目的是为了对于用户权限表可以减少数据库数据存储量,以及能够提高数据库查询的性能;

     

    3. 添加一个UserRightControl类,用于用户数据传递:

    代码
    public class UserRightControl 

        
    /// <summary> 
        
    /// 复合权限类型ID 
        
    /// </summary> 
        public int UserRightComplex { getset; } 

        
    /// <summary> 
        
    /// 权限数组 
        
    /// </summary> 
        private UserRight[] _rights; 
        
    public UserRight[] UserRights 
        { 
            
    get 
            { 
                
    if (_rights == null
                { 
                    
    //将复合权限类型ID 转换成 权限枚举类型数组 
                    _rights = UserRightComplex.ToUserRightArray(); 
                } 
                
    return _rights; 
            } 
        } 
    }

     

    4. 创建一个继承于IValueConverter接口的UserRightConverter

    代码
    public class UserRightConverter : IValueConverter 

        
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
        { 
            Visibility visibility 
    = Visibility.Collapsed; 
            UserRight[] rightArray 
    = (UserRight[])value; 
            UserRight right 
    = (UserRight)Enum.Parse(typeof(UserRight), (string)parameter, true); 

            UserRight state 
    = rightArray.FirstOrDefault(o => o == right); 
            
    if (state != UserRight.None) 
            { 
                visibility 
    = Visibility.Visible; 
            } 
            
    return visibility; 
        } 

        
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
        { 
            
    throw new NotImplementedException(); 
        } 
    }

    其中value是作为一个用户权限数组绑定过来的,parameter作为对应按钮的属性参数,如果value包含了parameter,该按钮就显示。

     

    5. 接着,创建一个UserRightButton.xaml的用户权限按钮控件:

    代码
    <UserControl x:Class="SilverlightAppDemo.UserRightButton" 
        xmlns
    ="http://schemas.microsoft.com/winfx/2006/xaml/presentation%22 
        xmlns:x="
    http://schemas.microsoft.com/winfx/2006/xaml%22 
        xmlns:uc
    ="clr-namespace:SilverlightAppDemo"> 
        
    <UserControl.Resources> 
                
    <uc:UserRightConverter x:Key="userRightConverter" /> 
            
    <Style x:Key="userright" TargetType="Button"> 
                
    <Setter Property="Height" Value="30"/> 
                
    <Setter Property="Width" Value="60"/> 
                
    <Setter Property="FontSize" Value="14"/> 
            
    </Style> 
        
    </UserControl.Resources> 
        
    <StackPanel HorizontalAlignment="Left"> 
            
    <StackPanel Orientation="Horizontal"> 
                
    <Button Content="查询" Visibility="{Binding UserRights, Converter={StaticResource userRightConverter}, ConverterParameter=Select}" Style="{StaticResource userright}"></Button> 
                
    <Button Content="修改" Visibility="{Binding UserRights, Converter={StaticResource userRightConverter}, ConverterParameter=Update}" Style="{StaticResource userright}"></Button> 
                
    <Button Content="添加" Visibility="{Binding UserRights, Converter={StaticResource userRightConverter}, ConverterParameter=Insert}" Style="{StaticResource userright}"></Button> 
                
    <Button Content="删除" Visibility="{Binding UserRights, Converter={StaticResource userRightConverter}, ConverterParameter=Delete}" Style="{StaticResource userright}"></Button> 
            
    </StackPanel> 
        
    </StackPanel> 
    </UserControl>

    该用户控件用于权限按钮的UI显示,注意到Button的Visibility属性,Binding UserRight 绑定了 UserRightControl类中的UserRights的权限数组;Converter={StaticResource userRightConverter} 将以userRightConverter为Key的UserRightConverter类 作为按钮的转换器,ConverterParameter后面的值为parameter。

     

    6. 最后,在Page.xaml上添加用户权限按钮控件:

    代码
    <UserControl x:Class="SilverlightAppDemo.Page" 
        xmlns
    ="http://schemas.microsoft.com/winfx/2006/xaml/presentation%22 
        xmlns:x="
    http://schemas.microsoft.com/winfx/2006/xaml%22 
        xmlns:uc
    ="clr-namespace:SilverlightAppDemo"> 
        
    <UserControl.Resources> 
            
    <uc:UserRightControl UserRightComplex="1" x:Key="urControl" /> 
        
    </UserControl.Resources> 
        
    <StackPanel> 
            
    <uc:UserRightButton x:Name="btnUserRight" DataContext="{StaticResource urControl}"/> 
        
    </StackPanel> 
    </UserControl>

    其中UserRightButton中的DataContext属性绑定了以urControl为Key的UserRightControl。

     

    7. 运行下程序

    当UserRightComplex为1时,

     

    当UserRightComplex为5时,

    当UserRightComplex为15时,

    本文主要介绍如何使用IValueConverter在应用场景中,欢迎继续交流。


    源代码下载:SilverlightAppDemo.rar

  • 相关阅读:
    Linux 下防火墙端口操作命令
    showDoc 安装
    jeckins 编译成功,启动失败问题总结
    20212923 202120222 《网络攻防实践》第一次作业_实践一:网络攻防环境的搭建
    再次搭建程序集报错
    面试不会的别扯
    一些莫名奇妙的错误(有点伤心)
    关于端口封禁的一些事
    算法方法
    Django配置日志
  • 原文地址:https://www.cnblogs.com/liping13599168/p/1726714.html
Copyright © 2020-2023  润新知