zoukankan      html  css  js  c++  java
  • DataGrid研究笔记-2

    上次写了焦点控制,这次讲一下,校验和错误提示。

    wpf自带有ValidationRule

    第一种:写说下ValidationRule的使用情况。

    继承ValidationRule, override Validate方法。

    然后xaml里

    <Style.Triggers>
                    <MultiTrigger>
                        <MultiTrigger.Conditions>
                            <Condition Property="Validation.HasError" Value="True" />
                            <Condition Property="IsFocused" Value="True" />
                        </MultiTrigger.Conditions>
                        <Setter Property="Validation.ErrorTemplate">
                            <Setter.Value>
                                <ControlTemplate>
                                    <Grid>
                                        <Grid.RowDefinitions>
                                            <RowDefinition Height="Auto" />
                                            <RowDefinition />
                                        </Grid.RowDefinitions>
                                        <AdornedElementPlaceholder Name="MyAdorner" />
    
                                        <Border Grid.Row="1"
                                                Height="20"
                                                Margin="10,-1,0,0"
                                                Background="#FFE2402F"
                                                CornerRadius="4"
                                                Opacity="30">
                                            <Border.Effect>
                                                <DropShadowEffect ShadowDepth="0" />
                                            </Border.Effect>
                                            <TextBlock Margin="8,0"
                                                       FontSize="11"
                                                       VerticalAlignment="Center"
                                                       Foreground="White"
                                                       Text="{Binding ElementName=MyAdorner,
                                                                      Path=AdornedElement.(Validation.Errors)[0].ErrorContent}"
                                                       TextWrapping="Wrap" />
                                        </Border>
                                    </Grid>
                                </ControlTemplate>
                            </Setter.Value>
                        </Setter>
                        <Setter Property="Foreground" Value="red" />
                    </MultiTrigger>
                    <Trigger Property="Validation.HasError" Value="True">
                        <Setter Property="Foreground" Value="red" />
                    </Trigger>
                </Style.Triggers>


    第二种:IDataErrorInfo类,可以在定义的ViewModel里继承,

    主要两个方法

    public string Error
    
    
    public string this[string columnName]

    xaml使用情况同第一中种。

    但是前面几种可以提示错误信息,但是有错误时,无法不让焦点移动。

    下面我说说第三种方法:

    首先定义接口:

     public interface IContextValidation
        {
            ValidationResult Validate(DependencyObject sender);
        }
    
     public interface IContextValidationPolicy
        {
            void Run(DependencyObject sender, object content);
        }


    然后扩展接口

    public abstract class CodeValidationBase : IContextValidation
        {
            public string MethodName { get; set; }
        }
    
    public abstract class CodePolicyBase : IContextValidationPolicy
        {
            public string MethodName { get; set; }
            public abstract void Run(System.Windows.DependencyObject sender, object content);
        }


    接下来实现接口

    public class ClientCodeValidation : CodeValidationBase
        {
            public override ValidationResult Validate(DependencyObject sender)
            {
                Requires.NotNull(sender, "sender");
                Requires.NotNull(this.MethodName, "MethodName");
                object obj=null;
                return (ValidationResult)sender.SafeInvoke(new Func<ValidationResult>(() =>
                {
                    var page = this.GetVisualParent<Window>(sender as Visual);
                    if (sender is TextBox)
                    {
                        obj = ((TextBox)sender).Text;
                    }
                    else if (sender is DataGridCell)
                    {
                        var temp = (sender as DataGridCell).Content;
                        if (temp is TextBox)
                        {
                            obj = ((TextBox)temp).Text;
                        }
                        else if (temp is TextBlock)
                        {
                            obj = ((TextBlock)temp).Text;
                        }
                    }
                    else
                    {
                        var textBoxBase = this.GetVisualChild<TextBox>(sender as Visual);
                        if (textBoxBase != null)
                        {
                            obj = ((TextBox)textBoxBase).Text;
                        }
                    }
                    if (page == null)
                    {
                        throw new InvalidOperationException("Cannot find page which owns sender");
                    }
                    return page.ReflectCallInstanceMethod<ValidationResult>(
                        this.MethodName, new Type[] { typeof(object) }, obj);
                }));
            }
    }
    public class KeepFocusPolicy : IContextValidationPolicy
        {
            public void Run(System.Windows.DependencyObject sender, object content)
            {
                Requires.NotNull(sender, "sender");
                var element = sender as FrameworkElement;
                if (element == null)
                {
                    throw new ArgumentException("sender must be FrameworkElement", "sender");
                }
                element.SafeInvoke(() => element.Focus());
            }
        }
    
    public sealed class ShowTipPolicy : IContextValidationPolicy
        {
            public TipAdornerPlacement Placement { get; set; }
    
            public void Run(System.Windows.DependencyObject sender, object content)
            {
                var element = sender as FrameworkElement;
                if (element == null) return;
    
                sender.SafeInvoke(() =>
                {
                    var message = content == null ? "输入错误" : content.ToString();
                    element.ShowTipAdorner(Placement, message);
                });
            }
        }

    最后我们就可以在焦点移动前,去做判断了:

    var myDataGridTextColumn = currentCellContainer.Column as MyDataGridTextColumn;
                    if (myDataGridTextColumn != null)
                    {
                        var validations = myDataGridTextColumn.Validations;
                        var errorPolicies = myDataGridTextColumn.ErrorPolicies;
                        bool hasError = false;
                        object errMessage = null;
                        validations.ForEach(o =>
                            {
                                var result = o.Validate(focuseElement);
                                if (!result.IsValid)
                                {
                                    hasError = true;
                                    errMessage = result.ErrorContent;
                                }
                            });
                        if (hasError)
                        {
                            errorPolicies.ForEach(o => o.Run(focuseElement, errMessage));
                            this.SetValue(CurrentCellProperty, new DataGridCellInfo(currentCellContainer));
                            //this.SetValue(MyCurrentCellProperty, currentCellContainer);
                            var temp = this.CurrentCell;
                            //focuseElement.Focus();
                            return;
                        }
                    }

    xmal里使用:

    <local:MyDataGridTextColumn Header="BBB" Width="100" Binding="{Binding B}">
                        <local:MyDataGridTextColumn.Validations>
                            <local:ClientCodeValidation MethodName="Validation"/>
                        </local:MyDataGridTextColumn.Validations>
                        <local:MyDataGridTextColumn.ErrorPolicies>
                            <local:ShowTipPolicy Placement="Right" />
                            <local:KeepFocusPolicy />
                        </local:MyDataGridTextColumn.ErrorPolicies>
                    </local:MyDataGridTextColumn>

    校验事件,写在前台,校验的时候会使用反射,调用。

     public ValidationResult Validation(object value)
            {
                if ((string)value == "5")
                {
                    return new ValidationResult(false, "不能为5");
                }
                return new ValidationResult(true, string.Empty);
            }
  • 相关阅读:
    linux下yum错误:[Errno 14] problem making ssl connection Trying other mirror.
    linux下sudo命令
    myeclipse修改编译器版本的方法 .
    java 使用POI读写Excel文件(兼容2003、2007)
    Google.ProtocolBuffers.dll 之.Net应用(一)
    禁止Grid、TreeGrid列排序和列菜单
    在VS2008中加入ExtJS智能提示
    教程地址
    ExtJS xtype 一览
    ExtJS中,将Grid表头中的全选复选框取消复选
  • 原文地址:https://www.cnblogs.com/gavinhuang/p/3305481.html
Copyright © 2011-2022 走看看