• 循序渐进介绍基于CommunityToolkit.Mvvm 和HandyControl的WPF应用端开发(8) -- 使用Converter类实现内容的转义处理


    在我们WPF应用端的时候,和WInform开发或者Vue前端开发一样,有时候也需要对内容进行转义处理,如把一些0,1数值转换为具体含义的文本信息,或者把一些布尔变量转换为是否等,都是常见的转换处理,本篇随笔介绍在WPF应用端对内容使用Converter类实现内容的转义处理的操作。

    1、使用Converter实现内容转义或者强调颜色

    一般在DataGrid中,我们往往都会根据需要对内容或者颜色进行一些转义处理,如下界面所示用户列表信息中,对性别和是否过期的内容进行颜色和内容的转义处理。

    在DataGrid的XAML代码中,如果是常规的内容,通过定义列名称即可显示,如下所示。

    <DataGridTextColumn
        Width="SizeToCells"
        Binding="{Binding Name}"
        Header="用户名称" />

    如果是日期或者字符串的格式处理,可以使用StringFormat的属性处理,如下所示。

    复制代码
    <DataGridTemplateColumn MinWidth="100" Header="创建时间">
        <DataGridTemplateColumn.CellTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding CreateTime, StringFormat=yyyy-MM-dd hh:mm}" />
            DataTemplate>
        DataGridTemplateColumn.CellTemplate>
    DataGridTemplateColumn>
    复制代码

    而如果需要转义,则需要设置Converter的对象类,我们的代码如下所示。

    复制代码
    <DataGridTemplateColumn MinWidth="60" Header="性别">
        <DataGridTemplateColumn.CellTemplate>
            <DataTemplate>
                <TextBlock Foreground="{Binding Gender, Converter={StaticResource GenderColorConverter}}" Text="{Binding Gender}" />
            DataTemplate>
        DataGridTemplateColumn.CellTemplate>
    DataGridTemplateColumn>
    <DataGridTemplateColumn MinWidth="60" Header="是否过期">
        <DataGridTemplateColumn.CellTemplate>
            <DataTemplate>
                <TextBlock Foreground="{Binding IsExpire, Converter={StaticResource BooleanToColorConverter}}" Text="{Binding IsExpire, Converter={StaticResource BooleanToYesNoStrConverter}}" />
            DataTemplate>
        DataGridTemplateColumn.CellTemplate>
    DataGridTemplateColumn>
    复制代码

     

    2、Converter转义类的编写和应用

    上面的转义处理中,可以对多个属性进行转义,如前景颜色或者Text文本等等。转义类的定义也比较简单,只需要实现IValueConverter接口即可,一般不需要双向的话,实现Convert函数即可,代码如下所示。

    复制代码
    /// 
    /// 用来转换性别字符串到颜色
    /// 
    internal class GenderColorConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value is null) return "";
    
            if(value.ToString() == "")
            {
                return "green";
            }
            else
            {
                return "red";
            }
        }
    
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
    复制代码

    或者

    复制代码
        public class NumberToYesNoStrConverter : IValueConverter
        {
            public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
            {
                var flag = ConvertToBoolean(value);
                return flag ? "" : "";
            }
    
            private bool ConvertToBoolean(object value)
            {
                if (value == null)
                    return false;
    
                return value switch
                {
                    float f => f != 0.0f,
                    double d => d != 0.0f,
                    int i => i != 0,
                    long l => l != 0.0f,
                    _ => throw new NotSupportedException($"value must be a number type, got {value?.GetType()}")
                };
            }
    
            public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) => throw new NotImplementedException();
        }
    复制代码
    复制代码
    public class String2VisibilityConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return string.IsNullOrEmpty((string)value) ? Visibility.Collapsed : Visibility.Visible;
        }
    
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return value != null && (Visibility)value == Visibility.Collapsed;
        }
    }
    
    public class String2VisibilityReConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return string.IsNullOrEmpty((string)value) ? Visibility.Visible : Visibility.Collapsed;
        }
    
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return value != null && (Visibility)value == Visibility.Collapsed;
        }
    }
    复制代码

    转义类的函数,可以参考很多案例进行收集一些常用的,也可以自己根据需要创建一些转义函数,虽然感觉比较麻烦一些,不过重用性较好。一般可以放在页面或者窗口的视图代码中,如下代码所示。

    复制代码
    <Page.Resources>
        <BooleanToVisibilityConverter x:Key="BoolToVisConverter" />
        <helpers:String2VisibilityConverter x:Key="String2VisibilityConverter" />
        <helpers:String2VisibilityReConverter x:Key="String2VisibilityReConverter" />
    Page.Resources>
    复制代码

    如果考虑整个App重用这些转义类的内容,也可以放在App.xaml,那么所有的转义函数就是全局可用的了,我倾向于这种方式,可以减少每个窗口或者页面的代码,比较简洁。

    复制代码
    <Application.Resources>
        <ResourceDictionary>
            
            <helpers:IntToBooleanConverter x:Key="IntToBooleanConverter" />
            <helpers:EnumToBooleanConverter x:Key="EnumToBooleanConverter" />
            <helpers:BooleanToYesNoStrConverter x:Key="BooleanToYesNoStrConverter" />
            <helpers:BooleanToColorConverter x:Key="BooleanToColorConverter" />
            <helpers:GenderColorConverter x:Key="GenderColorConverter" />
            ........................
    
        ResourceDictionary>
    Application.Resources>
    复制代码

    除了DataGrid中使用,我们也可以其他页面展示的地方使用Converter实现我们的转义效果,如下所示是编辑用户详细信息的页面,其中对性别颜色进行强调,对账户是否过期进行转义和颜色强调。

     其中Xaml的界面代码如下所示

    复制代码
    <WrapPanel
        Width="350"
        VerticalAlignment="Center"
        Orientation="Horizontal">
        <TextBlock Width="100" Text="账号过期" />
        <CheckBox
            HorizontalAlignment="Right"
            VerticalAlignment="Center"
            VerticalContentAlignment="Top"
            Content="{Binding ViewModel.Item.IsExpire, Converter={StaticResource BooleanToYesNoStrConverter}}"
            FontWeight="Bold"
            Foreground="{Binding ViewModel.Item.IsExpire, Converter={StaticResource BooleanToColorConverter}}"
            IsChecked="{Binding ViewModel.Item.IsExpire, UpdateSourceTrigger=PropertyChanged}"
            IsEnabled="{Binding ViewModel.IsEdit, Mode=OneWay}" />
    WrapPanel>
    复制代码

    另外,我们也可以使用它来控制一些UI元素的显示,如下对于编辑状态下,不显示用户的初始化密码的文本框架,如下所示。

    复制代码
    <TextBox
        x:Name="InitPassword"
        Width="350"
        Margin="5"
        hc:TitleElement.Title="初始密码"
        hc:TitleElement.TitlePlacement="Left"
        Style="{StaticResource TextBoxExtend}"
        Text="{Binding ViewModel.Item.Password, UpdateSourceTrigger=PropertyChanged}"
        Visibility="{Binding ViewModel.IsEdit, Converter={StaticResource Boolean2VisibilityReConverter}}" />
    复制代码

    以及对于角色处理的时候,我们创建角色的时候,仅仅显示简单信息,编辑的时候,显示更多的信息,如下界面代码控制。

    新建角色的时候,界面如下所示。

    编辑角色的时候,我们根据角色显示更多的信息,如下界面所示。

     

     3、不使用Converter类实现内容转义

     有时候,为了一些特殊的处理,我们可能不一定使用Converter来实现内容的转义,我们也可以直接处理,如下DataGrid里面的列处理,可以直接使用 Triggers 进行转义的处理,如下代码所示。

    复制代码
    <DataGridTemplateColumn Width="*" Header="授权类型">
        <DataGridTemplateColumn.CellTemplate>
            <DataTemplate>
                <TextBlock>
                    <TextBlock.Style>
                        <Style TargetType="TextBlock">
                            <Style.Triggers>
                                <DataTrigger Binding="{Binding Path=AuthorizeType}" Value="1">
                                    <Setter Property="Text" Value="白名单" />
                                    <Setter Property="Foreground" Value="Green" />
                                DataTrigger>
                                <DataTrigger Binding="{Binding Path=AuthorizeType}" Value="0">
                                    <Setter Property="Text" Value="黑名单" />
                                    <Setter Property="Foreground" Value="Red" />
                                DataTrigger>
                            Style.Triggers>
                        Style>
                    TextBlock.Style>
                TextBlock>
            DataTemplate>
        DataGridTemplateColumn.CellTemplate>
    DataGridTemplateColumn>
    复制代码

    这种处理,代码较多一些,而没法重用,但是贵在直接,而且能够一次性控制多个内容的处理。 

     以上就是在WPF应用端开发中使用Converter类实现内容的转义处理的一些应用心得和总结。

  • 相关阅读:
    [交互]实战问题2-413 Request Entity Too Large
    SpringBoot学习
    检查两个字符串数组是否相等
    C++新经典 | C++ 查漏补缺(类)
    ActivityThread应用进程
    Intel Cyclone 10 GX 收发器的时钟网络
    SpringBoot内置工具类,告别瞎写工具类了
    C语言结构体指针学习
    GAM注意力机制
    无人机覆盖路径规划综述
  • 原文地址:https://www.cnblogs.com/wuhuacong/p/17763967.html