WPF 검증

21377 단어 WPF

디렉토리:

  • ValidationRule 검증
  • Exception 검증
  • IDataErrorInfo 인증
  • Custom Control 검증

  •  

    1. ValidationRule 검증


    Validation Rule: Validation Rule의 Validate 방법을 통해 귀속된 속성을 검증합니다.그래서 우리의 용법은 Validation Rule를 계승하여 그의 Validate 방법을 다시 쓰는 것이다.예제
    public class RequiredRule : ValidationRule
    
        {
    
            public override ValidationResult Validate(object value, CultureInfo cultureInfo)
    
            {
    
                if (value == null)
    
                    return new ValidationResult(false, " !");
    
                if (string.IsNullOrEmpty(value.ToString()))
    
                    return new ValidationResult(false, " !");
    
    
    
                return new ValidationResult(true, null);
    
            }
    
        }

    <!--
    .csharpcode, .csharpcode pre
    {
    font-size: small;
    color: black;
    font-family: consolas, "Courier New", courier, monospace;
    background-color: #ffffff;
    /*white-space: pre;*/
    }
    .csharpcode pre { margin: 0em; }
    .csharpcode .rem { color: #008000; }
    .csharpcode .kwrd { color: #0000ff; }
    .csharpcode .str { color: #006080; }
    .csharpcode .op { color: #0000c0; }
    .csharpcode .preproc { color: #cc6633; }
    .csharpcode .asp { background-color: #ffff00; }
    .csharpcode .html { color: #800000; }
    .csharpcode .attr { color: #ff0000; }
    .csharpcode .alt
    {
    background-color: #f4f4f4;
    width: 100%;
    margin: 0em;
    }
    .csharpcode .lnum { color: #606060; }
    -->
    XAML에서는 오류 정보를 표시해야 합니다.
    <Window.Resources>
    
            <ControlTemplate x:Key="ErrorTemplate">
    
                <Border BorderBrush="Red" BorderThickness="1">
    
                    <AdornedElementPlaceholder/>
    
                </Border>
    
            </ControlTemplate>
    
            <Style TargetType="TextBox">
    
                <Setter Property="Validation.ErrorTemplate" Value="{StaticResource ErrorTemplate}">
    
                </Setter>
    
                <Style.Triggers>
    
                    <Trigger Property="Validation.HasError" Value="True">
    
                        <Setter Property="ToolTip" Value="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors)[0].ErrorContent}"/>
    
                    </Trigger>
    
                </Style.Triggers>
    
            </Style>
    
        </Window.Resources>
    
        <StackPanel>
    
            <TextBlock Text=" "/>
    
            <TextBox>
    
                <TextBox.Text>
    
                    <Binding Path="Name" UpdateSourceTrigger="PropertyChanged" ValidatesOnDataErrors="True">
    
                        <Binding.ValidationRules>
    
                            <ValidationRules:RequiredRule/>
    
                        </Binding.ValidationRules>
    
                    </Binding>
    
                </TextBox.Text>
    
            </TextBox>
    
            <TextBlock Text=" "/>
    
            <TextBox >
    
                <TextBox.Text>
    
                    <Binding Path="Age" UpdateSourceTrigger="PropertyChanged" ValidatesOnDataErrors="True">
    
                        <Binding.ValidationRules>
    
                            <ValidationRules:GreaterThanRule Number="10"/>
    
                        </Binding.ValidationRules>
    
                    </Binding>
    
                </TextBox.Text>
    
            </TextBox>
    
        </StackPanel>

    <!--
    .csharpcode, .csharpcode pre
    {
    font-size: small;
    color: black;
    font-family: consolas, "Courier New", courier, monospace;
    background-color: #ffffff;
    /*white-space: pre;*/
    }
    .csharpcode pre { margin: 0em; }
    .csharpcode .rem { color: #008000; }
    .csharpcode .kwrd { color: #0000ff; }
    .csharpcode .str { color: #006080; }
    .csharpcode .op { color: #0000c0; }
    .csharpcode .preproc { color: #cc6633; }
    .csharpcode .asp { background-color: #ffff00; }
    .csharpcode .html { color: #800000; }
    .csharpcode .attr { color: #ff0000; }
    .csharpcode .alt
    {
    background-color: #f4f4f4;
    width: 100%;
    margin: 0em;
    }
    .csharpcode .lnum { color: #606060; }
    -->
    이렇게 하면 오류 메시지가 ToolTip 및 빨간색 테두리로 표시됩니다.그러나 여기에 또 TextBox에 ToolTip을 설정하면 TextBox의 ToolTip을 우선적으로 선택합니다. 즉, 스타일의 ToolTip이 오류 정보를 만났을 때 표시되지 않고 TextBox의 ToolTip을 표시합니다.그래서 우리는 이 문제를 해결하기 위해 표시된 모델을 개선할 수 있다.
    <ControlTemplate x:Key="ErrorTemplate">
    
                <DockPanel LastChildFill="true">
    
                    <Border Background="Red" DockPanel.Dock="right" Margin="5,0,0,0" Width="20" Height="20" CornerRadius="10"
    
                                ToolTip="{Binding ElementName=customAdorner, Path=AdornedElement.(Validation.Errors)[0].ErrorContent}">
    
                        <TextBlock Text="!" VerticalAlignment="center" HorizontalAlignment="center" FontWeight="Bold" Foreground="white">
    
                        </TextBlock>
    
                    </Border>
    
                    <AdornedElementPlaceholder Name="customAdorner" VerticalAlignment="Center" >
    
                        <Border BorderBrush="red" BorderThickness="1" />
    
                    </AdornedElementPlaceholder>
    
                </DockPanel>
    
            </ControlTemplate>

    <!--
    .csharpcode, .csharpcode pre
    {
    font-size: small;
    color: black;
    font-family: consolas, "Courier New", courier, monospace;
    background-color: #ffffff;
    /*white-space: pre;*/
    }
    .csharpcode pre { margin: 0em; }
    .csharpcode .rem { color: #008000; }
    .csharpcode .kwrd { color: #0000ff; }
    .csharpcode .str { color: #006080; }
    .csharpcode .op { color: #0000c0; }
    .csharpcode .preproc { color: #cc6633; }
    .csharpcode .asp { background-color: #ffff00; }
    .csharpcode .html { color: #800000; }
    .csharpcode .attr { color: #ff0000; }
    .csharpcode .alt
    {
    background-color: #f4f4f4;
    width: 100%;
    margin: 0em;
    }
    .csharpcode .lnum { color: #606060; }
    -->

    2. Exception 검증


    Exception: 우리 xaml에 귀속된 대상은 속성입니다.그래서 Exception 검증은 속성의 변화를 통해 정상 여부를 판단하는 것이다.예:
     public int Age
    
            {
    
                get { return _age; }
    
                set
    
                {
    
                    if (value > 200)
    
                    {
    
                        throw new Exception(" 200");
    
                    }
    
                    _age = value;
    
                }
    
            }

    <!--
    .csharpcode, .csharpcode pre
    {
    font-size: small;
    color: black;
    font-family: consolas, "Courier New", courier, monospace;
    background-color: #ffffff;
    /*white-space: pre;*/
    }
    .csharpcode pre { margin: 0em; }
    .csharpcode .rem { color: #008000; }
    .csharpcode .kwrd { color: #0000ff; }
    .csharpcode .str { color: #006080; }
    .csharpcode .op { color: #0000c0; }
    .csharpcode .preproc { color: #cc6633; }
    .csharpcode .asp { background-color: #ffff00; }
    .csharpcode .html { color: #800000; }
    .csharpcode .attr { color: #ff0000; }
    .csharpcode .alt
    {
    background-color: #f4f4f4;
    width: 100%;
    margin: 0em;
    }
    .csharpcode .lnum { color: #606060; }
    -->
    똑같이 튀어나온 이상은 Xaml에도 표시됩니다.XAML이 함께 제공됩니다.이런 방식은 POCO의 설계 원칙을 파괴할 수 있다.

    3. IDataErrorInfo 검증


    IDataErrorInfo: 이 검증은 우리 실체 대상이 IDataErrorInfo를 계승함으로써 이루어집니다.클래스에 접근하기 위해this 인덱스를 설명합니다.
     public class BaseDataErrorInfo : IDataErrorInfo
    
        {
    
            private string _error;
    
    
    
            public string this[string columnName]
    
            {
    
                get { return GetErrorFor(columnName); }
    
            }
    
    
    
            public string Error
    
            {
    
                get { return _error; }
    
                set { _error = value; }
    
            }
    
    
    
            public virtual string GetErrorFor(string columnName)
    
            {
    
                return string.Empty;
    
            }
    
        }

    <!--
    .csharpcode, .csharpcode pre
    {
    font-size: small;
    color: black;
    font-family: consolas, "Courier New", courier, monospace;
    background-color: #ffffff;
    /*white-space: pre;*/
    }
    .csharpcode pre { margin: 0em; }
    .csharpcode .rem { color: #008000; }
    .csharpcode .kwrd { color: #0000ff; }
    .csharpcode .str { color: #006080; }
    .csharpcode .op { color: #0000c0; }
    .csharpcode .preproc { color: #cc6633; }
    .csharpcode .asp { background-color: #ffff00; }
    .csharpcode .html { color: #800000; }
    .csharpcode .attr { color: #ff0000; }
    .csharpcode .alt
    {
    background-color: #f4f4f4;
    width: 100%;
    margin: 0em;
    }
    .csharpcode .lnum { color: #606060; }
    -->
    public class Person : BaseDataErrorInfo
    
        {
    
            public string Name { get; set; }
    
    
    
            public override string GetErrorFor(string columnName)
    
            {
    
                if (columnName == "Name")
    
                    if (string.IsNullOrEmpty(Name))
    
                        return "Name  ";
    
    
    
                return base.GetErrorFor(columnName);
    
            }
    
    
    
        }

    <!--
    .csharpcode, .csharpcode pre
    {
    font-size: small;
    color: black;
    font-family: consolas, "Courier New", courier, monospace;
    background-color: #ffffff;
    /*white-space: pre;*/
    }
    .csharpcode pre { margin: 0em; }
    .csharpcode .rem { color: #008000; }
    .csharpcode .kwrd { color: #0000ff; }
    .csharpcode .str { color: #006080; }
    .csharpcode .op { color: #0000c0; }
    .csharpcode .preproc { color: #cc6633; }
    .csharpcode .asp { background-color: #ffff00; }
    .csharpcode .html { color: #800000; }
    .csharpcode .attr { color: #ff0000; }
    .csharpcode .alt
    {
    background-color: #f4f4f4;
    width: 100%;
    margin: 0em;
    }
    .csharpcode .lnum { color: #606060; }
    -->
    XAML이 함께 제공됩니다.

    4. Custom Control 검증


    여기서 나는 실체류를 오염시키고 싶지 않고 통용되는 Validate를 실현하고 싶다.내 xaml을 통해 연결된 속성과 컨트롤을 사용하고 싶습니다.ToolTip을 표시합니다.
      public abstract class Validator : FrameworkElement
    
        {
    
            static Validator()
    
            {
    
                DefaultStyleKeyProperty.OverrideMetadata(typeof(Validator), new FrameworkPropertyMetadata(typeof(Validator)));
    
            }
    
    
    
            public virtual string ErrorMessage { get { return string.Empty; } }
    
            public abstract bool InitialValidation();
    
            public FrameworkElement ElementName
    
            {
    
                get { return (FrameworkElement)GetValue(ElementNameProperty); }
    
                set { SetValue(ElementNameProperty, value); }
    
            }
    
    
    
            // Using a DependencyProperty as the backing store for ElementName.  This enables animation, styling, binding, etc...
    
            public static readonly DependencyProperty ElementNameProperty =
    
                DependencyProperty.Register("ElementName", typeof(FrameworkElement), typeof(Validator), new PropertyMetadata(null));
    
    
    
    
    
            public object Source
    
            {
    
                get { return (object)GetValue(SourceProperty); }
    
                set { SetValue(SourceProperty, value); }
    
            }
    
    
    
            // Using a DependencyProperty as the backing store for Source.  This enables animation, styling, binding, etc...
    
            public static readonly DependencyProperty SourceProperty =
    
                DependencyProperty.Register("Source", typeof(object), typeof(Validator), new UIPropertyMetadata(new PropertyChangedCallback(ValidPropertyPropertyChanged)));
    
    
    
            private static void ValidPropertyPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    
            {
    
                var validator = d as Validator;
    
                if (validator != null)
    
                    validator.SetSourceFromProperty();
    
                if (string.IsNullOrEmpty(e.NewValue.ToString()))
    
                {
    
                    if (validator != null)
    
                    {
    
                        validator.IsValid = validator.InitialValidation();
    
                        if (validator.ElementName.DataContext != null)
    
                            validator.ShowToolTip();
    
                        validator.IsValid = false;
    
                    }
    
                }
    
            }
    
    
    
            private void ShowToolTip()
    
            {
    
                if (IsValid)
    
                {
    
                    timer = new DispatcherTimer();
    
                    timer.Interval = TimeSpan.FromSeconds(1.5);
    
                    _toolTip = new ToolTip();
    
                    _toolTip.StaysOpen = true;
    
                    _toolTip.PlacementTarget = ElementName;
    
                    _toolTip.Placement = PlacementMode.Right;
    
    
    
                    _toolTip.Content = ErrorMessage;
    
                    _toolTip.IsOpen = true;
    
                    timer.Tick += (sender, args) =>
    
                                      {
    
                                          _toolTip.IsOpen = false;
    
                                          timer.Stop();
    
                                      };
    
                    timer.Start();
    
                }
    
    
    
            }
    
            private void SetSourceFromProperty()
    
            {
    
                var expression = this.GetBindingExpression(SourceProperty);
    
                if (expression != null && this.ElementName == null)
    
                    this.SetValue(Validator.ElementNameProperty, expression.DataItem as FrameworkElement);
    
    
    
            }
    
    
    
            private ToolTip _toolTip;
    
            private DispatcherTimer timer;
    
    
    
            public bool IsValid { get; set; }
    
        }

    <!--
    .csharpcode, .csharpcode pre
    {
    font-size: small;
    color: black;
    font-family: consolas, "Courier New", courier, monospace;
    background-color: #ffffff;
    /*white-space: pre;*/
    }
    .csharpcode pre { margin: 0em; }
    .csharpcode .rem { color: #008000; }
    .csharpcode .kwrd { color: #0000ff; }
    .csharpcode .str { color: #006080; }
    .csharpcode .op { color: #0000c0; }
    .csharpcode .preproc { color: #cc6633; }
    .csharpcode .asp { background-color: #ffff00; }
    .csharpcode .html { color: #800000; }
    .csharpcode .attr { color: #ff0000; }
    .csharpcode .alt
    {
    background-color: #f4f4f4;
    width: 100%;
    margin: 0em;
    }
    .csharpcode .lnum { color: #606060; }
    -->
    이것은 간단한 Validate 기류다.사상을 제공하다.기능이 미비하다.
    그리고 이 Validator를 물려받겠습니다.
    public class RequiredValidator : Validator
    
        {
    
            public override string ErrorMessage { get { return " "; } }
    
            public override bool InitialValidation()
    
            {
    
                if (Source == null)
    
                    return false;
    
                return string.IsNullOrEmpty(Source.ToString());
    
            }
    
        }

    <!--
    .csharpcode, .csharpcode pre
    {
    font-size: small;
    color: black;
    font-family: consolas, "Courier New", courier, monospace;
    background-color: #ffffff;
    /*white-space: pre;*/
    }
    .csharpcode pre { margin: 0em; }
    .csharpcode .rem { color: #008000; }
    .csharpcode .kwrd { color: #0000ff; }
    .csharpcode .str { color: #006080; }
    .csharpcode .op { color: #0000c0; }
    .csharpcode .preproc { color: #cc6633; }
    .csharpcode .asp { background-color: #ffff00; }
    .csharpcode .html { color: #800000; }
    .csharpcode .attr { color: #ff0000; }
    .csharpcode .alt
    {
    background-color: #f4f4f4;
    width: 100%;
    margin: 0em;
    }
    .csharpcode .lnum { color: #606060; }
    -->
    오류 메시지가 표시됩니다.
    InitialValidation 방법은 검증할 규칙입니다.
     
    코드

    좋은 웹페이지 즐겨찾기