循序渐进介绍基于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函数即可,代码如下所示。
/// <summary>
/// 用来转换性别字符串到颜色
/// </summary>
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类实现内容的转义处理的一些应用心得和总结。
循序渐进介绍基于CommunityToolkit.Mvvm 和HandyControl的WPF应用端开发(8) -- 使用Converter类实现内容的转义处理的更多相关文章
- 基于SqlSugar的开发框架循序渐进介绍(3)-- 实现代码生成工具Database2Sharp的整合开发
我喜欢在一个项目开发模式成熟的时候,使用代码生成工具Database2Sharp来配套相关的代码生成,对于我介绍的基于SqlSugar的开发框架,从整体架构确定下来后,我就着手为它们量身定做相关的代码 ...
- 推荐一个基于Vue2.0的的一款移动端开发的UI框架,特别好用。。。
一丶YDUI 一只注重审美,且性能高效的移动端&微信UI. 下面为地址自己研究去吧! 我的项目正在用,以前用的Mint-ui但是现在感觉还是这个好一点,官方给出的解释很清楚,很实用. 官方地址 ...
- 基于SqlSugar的开发框架循序渐进介绍(4)-- 在数据访问基类中对GUID主键进行自动赋值处理
我们在设计数据库表的时候,往往为了方便,主键ID一般采用字符串类型或者GUID类型,这样对于数据库表记录的迁移非常方便,而且有时候可以在处理关联记录的时候,提前对应的ID值.但有时候进行数据记录插入的 ...
- 基于SqlSugar的开发框架循序渐进介绍(5)-- 在服务层使用接口注入方式实现IOC控制反转
在前面随笔,我们介绍过这个基于SqlSugar的开发框架,我们区分Interface.Modal.Service三个目录来放置不同的内容,其中Modal是SqlSugar的映射实体,Interface ...
- 基于SqlSugar的开发框架循序渐进介绍(6)-- 在基类接口中注入用户身份信息接口
在基于SqlSugar的开发框架中,我们设计了一些系统服务层的基类,在基类中会有很多涉及到相关的数据处理操作的,如果需要跟踪具体是那个用户进行操作的,那么就需要获得当前用户的身份信息,包括在Web A ...
- 基于SqlSugar的开发框架循序渐进介绍(8)-- 在基类函数封装实现用户操作日志记录
在我们对数据进行重要修改调整的时候,往往需要跟踪记录好用户操作日志.一般来说,如对重要表记录的插入.修改.删除都需要记录下来,由于用户操作日志会带来一定的额外消耗,因此我们通过配置的方式来决定记录那些 ...
- 基于SqlSugar的开发框架循序渐进介绍(12)-- 拆分页面模块内容为组件,实现分而治之的处理
在早期的随笔就介绍过,把常规页面的内容拆分为几个不同的组件,如普通的页面,包括列表查询.详细资料查看.新增资料.编辑资料.导入资料等页面场景,这些内容相对比较独立,而有一定的代码量,本篇随笔介绍基于V ...
- 基于SqlSugar的开发框架循序渐进介绍(13)-- 基于ElementPlus的上传组件进行封装,便于项目使用
在我们实际项目开发过程中,往往需要根据实际情况,对组件进行封装,以更简便的在界面代码中使用,在实际的前端应用中,适当的组件封装,可以减少很多重复的界面代码,并且能够非常简便的使用,本篇随笔介绍基于El ...
- 基于SqlSugar的开发框架循序渐进介绍(14)-- 基于Vue3+TypeScript的全局对象的注入和使用
刚完成一些前端项目的开发,腾出精力来总结一些前端开发的技术点,以及继续完善基于SqlSugar的开发框架循序渐进介绍的系列文章,本篇随笔主要介绍一下基于Vue3+TypeScript的全局对象的注入和 ...
- 基于SqlSugar的开发框架循序渐进介绍(17)-- 基于CSRedis实现缓存的处理
在一个应用系统的开发框架中,往往很多地方需要用到缓存的处理,有些地方是为了便于记录用户的数据,有些地方是为了提高系统的响应速度,如有时候我们在发送一个短信验证码的时候,可以在缓存中设置几分钟的过期时间 ...
随机推荐
- Taurus .Net Core 微服务开源框架:Admin 插件【3】 - 指标统计管理
前言: 继上篇:Taurus .Net Core 微服务开源框架:Admin 插件[2] - 系统环境信息管理 本篇继续介绍下一个内容: 1.系统指标节点:Metric - API 界面 界面图如下: ...
- 查询mysql数据库目前有哪些链接 具体ip及数量
SELECT substring_index(host, ':',1) AS host_name,state,count(*) FROM information_schema.processlist ...
- 利用java来实现计算器的加减乘除
package bag; import java.util.Scanner; public class Demo06 { public static void main(String[] args) ...
- BUUCTF-Misc-荷兰宽带数据泄露(RouterPassView的使用)
题目 下载附件是一个bin文件 这里用的一个工具RouterPassView--路由器密码查看工具 路由器的备份文件通常包含了像您的ISP的用户名重要数据/密码,路由器的登录密码,无线网络的KEY. ...
- bitfield
bitfield 作用 位域修改 溢出控制 原理 通过对redis字符串二进制形式进行操作,通过改变其值的作用 更具体 将一个Redis字符串看作是一个由二进制位组成的数组. 并能对变长位宽和任意没有 ...
- clickhouse 与 zookeeper
目录 clickhouse 设置中的 zookeeper 配置 参数说明 配置示例 [预发生产] ClickHouse Keeper 四字母命令 clickhouse 设置中的 zookeeper 配 ...
- 剪切图片, 原文自https://blog.csdn.net/sinat_41104353/article/details/85209456
因为在 OpenCV2 里面,所有的东西都是 numpy array 即 np.ndarray1,所以使用 opencv 剪切图像主要原理是用 ndarray 的切片.一张图片基本上都是三维数组:行, ...
- Django: django.core.exceptions.ImproperlyConfigured: Could not resolve URL for hyperlinked relationship using view name "game-detail".
错误原因:在序列化时,使用了参数`url`,但在`urls.py`文件中,没有使用命名 # urls.py from django.urls import path from RESTSerializ ...
- Django: You are trying to add a non-nullable field 'name' to mainnav without a default; we can't do that (the database needs something to populate existing rows).
错误原因: 语句中缺少默认值 class Main(models.Model): img = models.CharField(max_length=255) name = models.CharFi ...
- 注意!JAVA中的值传递
前言:今天在解决一个问题时,程序总是不能输出正确值,分析逻辑思路没问题后,发现原来是由于函数传递导致了这个情况. LeetCode 113 问题:给你二叉树的根节点root和一个整数目标和target ...