WPF MVVM Convert

WPF MVVM Convert在日常需求中不同的应用场景:

核心:将所有收到的值转换成views属性需求所需的值类型: 例如以下几种:需求场景:
1.Boolean To other
2.textbox 输入值限制
(1)整型(2)浮点型(3)正负数
3.多值传入

IMultiValueConverter 、 IValueConverter

IMultiValueConverterIValueConverter 是 WPF (Windows Presentation Foundation) 中用于数据绑定的接口。它们允许你在绑定数据时执行自定义转换逻辑,以便将数据从一种形式转换为另一种形式。这两个接口通常用于 XAML 中的数据绑定操作:
IValueConverter接口通常用于将单个值进行转换,而 IMultiValueConverter则用于多个值的转换。下面是它们的简要介绍:
俩个接口包含两个方法:Convert ConvertBack
Convert 方法用于将绑定源的值转换为目标值。
ConvertBack 方法则用于将目标值转换回源值(在双向绑定时使用)。
IMultiValueConverterConvert 方法用于将绑定源的多个值进行转换,通常用于处理多个输入值的情况。
这些接口提供了灵活的方式来自定义数据绑定的转换行为,帮助开发人员在 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>
  • 9
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值