zoukankan      html  css  js  c++  java
  • WPF Binding转换与校验

    Binding是WPF的核心,而数据的转换与校验是与Binding配套的,其重要性不言而喻,前面介绍了WPF的Binding,现在来看下Converter&Validation。本文目标是以简单的Demo展示Converter&Validation的用法。

    Binding用于数据有效性校验的是Binding的ValidationRules属性,用于数据类型转换的是Binding的Converter属性

    当Source端Path所关联的数据与Target目标属性数据类型不一致是,我们可以添加数据转换器。给出一个Demo。

    首先在xaml界面中定义一个Grid。

         <Grid>
            <TextBlock x:Name="txtMsg" Text="{Binding ElementName=txtBox, Path=(Validation.Errors)[0].ErrorContent}" Foreground="Red" FontWeight="Bold" Margin="34,12,161,280" />
    
            <DataGrid  AutoGenerateColumns="False" Margin="34,48,44,21" Name="dataGrid1" DataContext="{Binding}">
                <DataGrid.Columns>
                    <DataGridTemplateColumn Header="Id" Width="*" IsReadOnly="True">
                        <DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <TextBlock  FontSize="16" Text="{Binding Id}" Background="{Binding Id,Converter={StaticResource IdConverter1}}"/>
                            </DataTemplate>
                        </DataGridTemplateColumn.CellTemplate>
                    </DataGridTemplateColumn>
                    <DataGridTemplateColumn Header="Name" Width="2*" IsReadOnly="True">
                        <DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <!--<TextBlock Text="{Binding Name}"/>-->
                                <TextBlock x:Name="txtBox"  Validation.ErrorTemplate="{StaticResource errorTemplate}" Validation.Error="txtBox_Error" >
                                    <TextBlock.Text>
                                        <Binding Path="Name" NotifyOnValidationError="True" >
                                            <Binding.ValidationRules>
                                                <local:NameValidationRule  ValidatesOnTargetUpdated="True" />
                                            </Binding.ValidationRules>
                                        </Binding>
                                    </TextBlock.Text>
                                </TextBlock>
                            </DataTemplate>
                        </DataGridTemplateColumn.CellTemplate>
                    </DataGridTemplateColumn>
                    <DataGridTemplateColumn Header="Age" Width="*" IsReadOnly="True">
                        <DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <TextBlock Text="{Binding Age}"/>
                            </DataTemplate>
                        </DataGridTemplateColumn.CellTemplate>
                    </DataGridTemplateColumn>
                </DataGrid.Columns>
    
            </DataGrid>
        </Grid>

    下面自定义一个DataTable对象,作为Grid的数据源。

    using System.Data;
    
    namespace ConverterAndValidation
    {
       public class ClassData
        {
            /// <summary>
            /// 手动创建一个DataTable
            /// </summary>
            /// <returns></returns>
            public static DataTable GetDataTable()
            {
                DataTable dt = new DataTable();
                dt.Columns.Add("Id");
                dt.Columns.Add("Name");
                dt.Columns.Add("Age");
                //
                for (int i = 1; i <= 10; i++)
                {
                    DataRow dr = dt.NewRow();
                    dr.ItemArray = new object[] { i, "DebugLZQ"+i, 25+i };
                    dt.Rows.Add(dr);
                }
    
                return dt;
            }
        }
    }

    Binding如下:

    DataTable dt = ClassData.GetDataTable();
    dataGrid1.ItemsSource = dt.DefaultView;

    为了进行转换需要实现IValueConverter接口

    using System;
    using System.Windows.Data;
    using System.Windows.Media;
    
    namespace ConverterAndValidation
    {
        class IdConverter:IValueConverter
        {
            #region IValueConverter 成员
    
            public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
            {            
                int id = int.Parse(value.ToString());
                if (id == 1)
                    return new SolidColorBrush(Colors.Silver );
                if (id == 2)
                    return new SolidColorBrush(Colors.Teal );
                else
                    return new SolidColorBrush(Colors.Gold );
            }
    
            public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
            {
                throw new NotImplementedException();
            }
    
            #endregion
        }
    }

    如何消费这个IdConverter呢?
    添加一个xmlns

    xmlns:local="clr-namespace:ConverterAndValidation"

    添加Window.Resources资源

    <local:IdConverter x:Key="IdConverter1"/>

    在Binding处

    <TextBlock  FontSize="16" Text="{Binding Id}" Background="{Binding Id,Converter={StaticResource IdConverter1}}"/>

    下面同样以这个例子,写数据校验的Demo。

     为了进行校验,需要准备一个抽象类ValidationRule的派生类。

    using System.Windows.Controls;
    
    namespace ConverterAndValidation
    {
        class NameValidationRule:ValidationRule
        {
            public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)
            {
                string name = value.ToString();
                if (name!= "DebugLZQ5")
                {
                    return new ValidationResult(true, null);
                }
                return new ValidationResult(false, "Error Name,Validation Failed.");
            }
        }
    }

    如何消费这个Validation?在Window.Resources中添加

    <local:NameValidationRule x:Key="NameValidationRule1"/>
            <ControlTemplate x:Key="errorTemplate">
                <!--<StackPanel>
                    <TextBlock Foreground="Red">Invalid Value!!!</TextBlock>                
                    <AdornedElementPlaceholder/>
                </StackPanel>-->
                <DockPanel>
                    <TextBlock Foreground="Red">Invalid Value!!!</TextBlock>
                    <AdornedElementPlaceholder/>
                </DockPanel>
            </ControlTemplate>

    Binding部分

    <TextBlock x:Name="txtBox"  Validation.ErrorTemplate="{StaticResource errorTemplate}" Validation.Error="txtBox_Error" >
       <TextBlock.Text>
          <Binding Path="Name" NotifyOnValidationError="True" >
              <Binding.ValidationRules>
                 <local:NameValidationRule  ValidatesOnTargetUpdated="True" />
              </Binding.ValidationRules>
          </Binding>
       </TextBlock.Text>
    </TextBlock>

    txtBox_Error如下

            private void txtBox_Error(object sender, ValidationErrorEventArgs e)
            {
                if (e.Action == ValidationErrorEventAction.Added)    // Validation Error Occurred
                {
                    txtMsg.Text = e.Error.ErrorContent.ToString();                
                }
                else                        // No Error
                {
                    txtMsg.Text = "";                
                }
    
            }

    程序的运行结果如下:

     附:程序完整的xaml如下:

    View Code
    <Window x:Class="ConverterAndValidation.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            
            xmlns:local="clr-namespace:ConverterAndValidation"
            
            Title="MainWindow" Height="350" Width="525">
        <Window.Resources>
            <local:IdConverter x:Key="IdConverter1"/>
            <local:NameValidationRule x:Key="NameValidationRule1"/>
            <ControlTemplate x:Key="errorTemplate">
                <!--<StackPanel>
                    <TextBlock Foreground="Red">Invalid Value!!!</TextBlock>                
                    <AdornedElementPlaceholder/>
                </StackPanel>-->
                <DockPanel>
                    <TextBlock Foreground="Red">Invalid Value!!!</TextBlock>
                    <AdornedElementPlaceholder/>
                </DockPanel>
            </ControlTemplate>
       
        </Window.Resources>
    
        <Grid>
            <TextBlock x:Name="txtMsg" Text="{Binding ElementName=txtBox, Path=(Validation.Errors)[0].ErrorContent}" Foreground="Red" FontWeight="Bold" Margin="34,12,161,280" />
    
            <DataGrid  AutoGenerateColumns="False" Margin="34,48,44,21" Name="dataGrid1" DataContext="{Binding}">
                <DataGrid.Columns>
                    <DataGridTemplateColumn Header="Id" Width="*" IsReadOnly="True">
                        <DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <TextBlock  FontSize="16" Text="{Binding Id}" Background="{Binding Id,Converter={StaticResource IdConverter1}}"/>
                            </DataTemplate>
                        </DataGridTemplateColumn.CellTemplate>
                    </DataGridTemplateColumn>
                    <DataGridTemplateColumn Header="Name" Width="2*" IsReadOnly="True">
                        <DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <!--<TextBlock Text="{Binding Name}"/>-->
                                <TextBlock x:Name="txtBox"  Validation.ErrorTemplate="{StaticResource errorTemplate}" Validation.Error="txtBox_Error" >
                                    <TextBlock.Text>
                                        <Binding Path="Name" NotifyOnValidationError="True" >
                                            <Binding.ValidationRules>
                                                <local:NameValidationRule  ValidatesOnTargetUpdated="True" />
                                            </Binding.ValidationRules>
                                        </Binding>
                                    </TextBlock.Text>
                                </TextBlock>
                            </DataTemplate>
                        </DataGridTemplateColumn.CellTemplate>
                    </DataGridTemplateColumn>
                    <DataGridTemplateColumn Header="Age" Width="*" IsReadOnly="True">
                        <DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <TextBlock Text="{Binding Age}"/>
                            </DataTemplate>
                        </DataGridTemplateColumn.CellTemplate>
                    </DataGridTemplateColumn>
                </DataGrid.Columns>
    
            </DataGrid>
        </Grid>
    </Window>
  • 相关阅读:
    番茄土豆:小小生产力工具
    ubuntu下thrift的安装
    番茄工作法:试试看?
    python利用thrift连接hive
    如何预测用户query意图 « 搜索技术博客-淘宝
    笔记:Ubuntu下快速开始使用Python Thrift | 孙立文的博客
    hive使用
    checkout centos is x86_64 or 32bit
    溢泰的休閒世界 溢泰的 CentOS 5.x 系統與內建軟體安裝筆記整理
    番茄工作法_Feisky_新浪博客
  • 原文地址:https://www.cnblogs.com/DebugLZQ/p/2794046.html
Copyright © 2011-2022 走看看