WPF MVVM Convert在日常需求中不同的应用场景:
核心
:将所有收到的值转换成views属性需求所需的值类型: 例如以下几种:需求场景:
1.Boolean To other
2.textbox 输入值限制
(1)整型
(2)浮点型
(3)正负数
3.多值传入
IMultiValueConverter 、 IValueConverter
IMultiValueConverter
和 IValueConverter
是 WPF (Windows Presentation Foundation) 中用于数据绑定的接口。它们允许你在绑定数据时执行自定义转换逻辑,以便将数据从一种形式转换为另一种形式。这两个接口通常用于 XAML 中的数据绑定操作:
IValueConverter
接口通常用于将单个值进行转换,而 IMultiValueConverter
则用于多个值
的转换。下面是它们的简要介绍:
俩个接口包含两个方法:Convert
和ConvertBack
。
Convert
方法用于将绑定源的值转换为目标值。
ConvertBack
方法则用于将目标值转换回源值(在双向绑定时使用)。
IMultiValueConverter
的Convert
方法用于将绑定源的多个值进行转换,通常用于处理多个输入值的情况。
这些接口提供了灵活的方式来自定义数据绑定
的转换行为,帮助开发人员在 UI 中展示和操作数据时更加灵活和方便。在实际编码过程中,你可以根据具体的需求选择合适的接口,并实现自己的转换逻辑
。
希望这个解释能够帮助你更好地理解这两个接口的作用和用法。
1.单值传入及判断IValueConverter
1.1View
<UserControl x:Class="Client.Views.UiViews"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Client.Views"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Client.Views"
xmlns:vm="clr-namespace:Client.ViewModels"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<UserControl.Resources>
<local:BoolToBackground x:Key="boolToBackground" />
<local:NumericValueConverter x:Key="NumericValueConverter" />
</UserControl.Resources>
<Grid >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.2*"/>
<ColumnDefinition Width="0.2*"/>
</Grid.ColumnDefinitions>
<Label Grid.Column="0"
Content="{Binding labelValue,
Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged}">
</Label>
<TextBox Grid.Column="1"
BorderBrush="Transparent"
Width="100" Height="30"
TextAlignment="Left"
Background="#e0e0e0"
Text="{Binding TextValue,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay,
Converter={StaticResource NumericValueConverter}}"
HorizontalAlignment="Center" VerticalAlignment="Center" >
</TextBox>
</Grid>
</UserControl>
1.2 View.Xmal.cs 继承IValueConverter接口:
以下是输入框只允许输入非负数值型
数据的转换示例:
1.2.1 只允许一个小数点且小数点不在首位
using Client.ViewModels;
using System;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Windows.Data;
using System.Windows.Media;
namespace Client.Views
{
public partial class Teaching : System.Windows.Controls.UserControl
{
public Teaching()
{
InitializeComponent();
DataContext = ViewModel.Instance;
}
}
public class NumericValueConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is string text)
{
// 过滤非数值字符
int dotCount = 0; // 记录小数点的数量
string numericText = new string(text.Where(c =>
{
if (char.IsDigit(c))
{
return true; // 如果是数字,保留
}
else if (c == '.' && dotCount == 0)
{
dotCount++; // 如果是小数点且之前未出现过小数点,则保留
return true;
}
else
{
return false; // 其他情况舍弃
}
}).ToArray());
if (numericText.StartsWith("."))
{
if (numericText.Length > 1)
{
numericText = numericText.Substring(1, numericText.Length - 1);
}
}
return numericText;
}
return "0";
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
// 这里可以根据需要进行反向转换
return value;
}
}
}
若存在负数
需求则只需将校验修改为以下:
1.2.2 允许输入一位小数点及首位负号的数值型数据
if (value is string text)
{
StringBuilder numericTextBuilder = new StringBuilder();
bool isNegativeAllowed = true;
bool isDecimalPointAllowed = true;
foreach (char c in text)
{
if (char.IsDigit(c))
{
numericTextBuilder.Append(c);
}
else if (c == '-' && isNegativeAllowed && numericTextBuilder.Length == 0)
{
numericTextBuilder.Append(c);
isNegativeAllowed = false; // 禁止负号再次出现
}
else if (c == '.' && isDecimalPointAllowed && numericTextBuilder.Length > 0)
{
numericTextBuilder.Append(c);
isDecimalPointAllowed = false; // 禁止小数点再次出现
}
}
string numericText = numericTextBuilder.ToString();
return numericText;
}
2 多值传入IMultiValueConverter:
例如:在 DataGrid
中经常会遇到多行
数据,其中某一行有特殊需求
,这个时候就需要用到另外一个接口IMultiValueConverter
以下是简单的代码示例:
2.1 View.Xaml.cs
public class BoolToBackground : IMultiValueConverter
{
public object Convert(object[] value, Type targetType, object parameter, CultureInfo culture)
{
//核心在于object[] value为多参
// 假设value是一个整数,用于确定图片路径
bool bo = (bool)value[0];
var color = Brushes.Red ;
if (value[1].ToString()== "Error")
{
color=bo ? Brushes.LightGray : Brushes.Red;
}
else
{
color = bo ? Brushes.Green : Brushes.LightGray;
}
return color;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
2.2 View
详细引用请见1.1
<Grid >
<DataGrid Background="White" Grid.Row="1"
ItemsSource="{Binding DataGridList}"
CanUserResizeRows="False"
CanUserResizeColumns="False"
CanUserReorderColumns="False"
AutoGenerateColumns="False" IsReadOnly="True"
ScrollViewer.HorizontalScrollBarVisibility="Hidden"
ScrollViewer.VerticalScrollBarVisibility="Hidden">
<DataGrid.ColumnHeaderStyle>
<Style TargetType="DataGridColumnHeader">
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="Background" Value="#E8e8e8"/>
<Setter Property="BorderThickness" Value="1,1,1,1"/>
<Setter Property="BorderBrush" Value="#ffffff"/>
<Setter Property="Height" Value="50"/>
</Style>
</DataGrid.ColumnHeaderStyle>
<DataGrid.Columns>
<DataGridTemplateColumn Width="0.13*">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate >
<Grid Background="White">
<TextBlock x:Name="TextBlockName"
Text="{Binding Name}"
HorizontalAlignment="Center"
VerticalAlignment="Center">
</TextBlock>
</Grid>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="X1" Width="0.125*">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate >
<Button
Style="{StaticResource CircularButtonStyle1}"
HorizontalAlignment="Center"
VerticalAlignment="Center"
x:Name="X1" >
<Button.Background>
<MultiBinding Converter="{StaticResource boolToBackground}">
<Binding Path="X1"/>
<Binding Path="Name"/>
</MultiBinding>
</Button.Background>
</Button>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Z" Width="0.125*">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate >
<Button
Style="{StaticResource CircularButtonStyle1}"
HorizontalAlignment="Center"
VerticalAlignment="Center"
>
<Button.Background>
<MultiBinding Converter="{StaticResource boolToBackground}">
<Binding Path="Z"/>
<Binding Path="Name"/>
</MultiBinding>
</Button.Background>
</Button>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Y" Width="0.125*">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate >
<Button
Style="{StaticResource CircularButtonStyle1}"
HorizontalAlignment="Center"
VerticalAlignment="Center"
>
<Button.Background>
<MultiBinding Converter="{StaticResource boolToBackground}">
<Binding Path="Y"/>
<Binding Path="Name"/>
</MultiBinding>
</Button.Background>
</Button>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="T" Width="0.125*">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate >
<Button
Style="{StaticResource CircularButtonStyle1}"
HorizontalAlignment="Center"
VerticalAlignment="Center"
>
<Button.Background>
<MultiBinding Converter="{StaticResource boolToBackground}">
<Binding Path="T"/>
<Binding Path="Name"/>
</MultiBinding>
</Button.Background>
</Button>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</Grid>