2016-12-07 1 views
1

ユーザーがフィールドよりも長い文字列を入力しようとすると、アイコン、ツールチップまたはチャットバブルをフィールドに表示しようとしています。私はこれを広範囲に捜してきましたが、私はこれが簡単な解決策を持たないように思われます。私は、入力が無効なときにフィールドの外観を変更する簡単な解決策を見つけましたが、警告を点滅させてフィールド内の正当な以前の値を保持するものはありません。これを達成するにはどうすればいいですか?フィールドトリガーの長さの検証エラーアイコン

+1

:「分野での法律以前の値を保持しています」。つまずいている特定の問題(ヒント:質問に疑問符はありません)? – Sinatr

+0

[ErrorTemplate'](https://www.codeproject.com/tips/690130/simple-validation-in-wpf)のように? –

答えて

0

適切な方法は、ErrorTemplateValidationRuleです。

まず、文字列の長さをチェックするものがある場合は、ValidationRuleが必要です。

public class StringLengthRule : ValidationRule 
{ 
    public int MaxLength { get; set; } 

    public override ValidationResult Validate(object value, CultureInfo cultureInfo) 
    { 
     if (((string)value).Length > MaxLength) 
      return new ValidationResult(false, "Input too long!"); 
     return new ValidationResult(true, null); 
    } 
} 

あなたが例えば、あなたのビューの結合にそれを添付することができます。 (私はスタイルとテンプレートを用意しました:

<TextBox> 
    <TextBox.Text> 
     <Binding RelativeSource="{RelativeSource AncestorType=local:MainWindow}" 
       UpdateSourceTrigger="PropertyChanged" <!-- or LostFocus --> 
       Path="Text"> 
      <Binding.ValidationRules> 
       <local:StringLengthRule MaxLength="15"/> 
      </Binding.ValidationRules> 
     </Binding> 
    </TextBox.Text> 
</TextBox> 

あなたのスタイル/テンプレートに応じて、これはこのようになります。この回答の下部にある)

Error Template

これは、あまりにも内部エラーのために動作します。あなたはたとえば、int型にバインドする場合:

Example 2

あなたはすべての入力がダイアログを閉じる前に有効であるかどうかを確認するために同じ検証を使用することができます。

public static class ValidationHelper 
{ 
    public static bool IsValid(DependencyObject obj) 
    { 
     // The dependency object is valid if it has no errors and all 
     // of its children (that are dependency objects) are error-free. 
     return !Validation.GetHasError(obj) && 
     LogicalTreeHelper.GetChildren(obj) 
     .OfType<DependencyObject>() 
     .All(IsValid); 
    } 

    public static bool ShowValidHint(DependencyObject dependencyObject) 
    { 
     if (IsValid(dependencyObject)) return true; 

     MessageBox.Show(Strings.WarningInput, Strings.InputError, MessageBoxButton.OK, MessageBoxImage.Warning); 
     return false; 
    } 
} 

使用法:として

private void btnOk_Click(object sender, RoutedEventArgs e) 
{ 
    ((Button)sender).Focus(); 
    if (ValidationHelper.ShowValidHint(this)) 
     DialogResult = true; 
    else 
     // show error 
} 

法的前回値を一部を保持します。これは、PropertyMetadataPropertyChangedCallbackまたはCoerceValueCallback、または(代わりにINotifyPropertyChangedを使用している場合は)プロパティ設定ツールを使用するのが最適です。私は個人的にそれに反対することを勧めます。値を元に戻すと値は再び有効になり、キーボードをタイプしている人は自分が何を間違ったのか分からなくなるかもしれません。


私はこのテンプレートがどこにあるのか覚えていませんが、このような年齢の場合に使用しています。

コントロールテンプレート

<ControlTemplate x:Key="TextBoxErrorTemplate"> 
    <StackPanel Orientation="Horizontal"> 
     <!-- Defines TextBox outline border and the ToolTipCorner --> 
     <Border x:Name="border" BorderThickness="1.25" BorderBrush="#FFDC000C"> 
      <Grid> 
       <Polygon x:Name="toolTipCorner" Grid.ZIndex="2" Margin="-1" Points="9,9 9,0 0,0" Fill="#FFDC000C" HorizontalAlignment="Right" 
        VerticalAlignment="Top" IsHitTestVisible="True"/> 
       <Polyline Grid.ZIndex="3" Points="10,10 0,0" Margin="-1" HorizontalAlignment="Right" StrokeThickness="1.5" 
           StrokeEndLineCap="Round" StrokeStartLineCap="Round" Stroke="White" VerticalAlignment="Top" IsHitTestVisible="True"/> 
       <AdornedElementPlaceholder x:Name="adorner"/> 
      </Grid> 
     </Border> 
     <!-- Defines the Popup --> 
     <Popup x:Name="placard" AllowsTransparency="True" PopupAnimation="Fade" Placement="Top" PlacementTarget="{Binding ElementName=toolTipCorner}" PlacementRectangle="10,-1,0,0"> 
      <!-- Used to reposition Popup when dialog moves or resizes --> 
      <Popup.Style> 
       <Style TargetType="{x:Type Popup}"> 
        <Style.Triggers> 
         <!-- Shows Popup when TextBox has focus --> 
         <DataTrigger Binding="{Binding ElementName=adorner, Path=AdornedElement.IsFocused}" Value="True"> 
          <Setter Property="IsOpen" Value="True"/> 
         </DataTrigger> 
         <!-- Shows Popup when mouse hovers over ToolTipCorner --> 
         <DataTrigger Binding="{Binding ElementName=toolTipCorner, Path=IsMouseOver}" Value="True"> 
          <Setter Property="IsOpen" Value="True"/> 
         </DataTrigger> 
         <!-- Hides Popup when window is no longer active --> 
         <DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=IsActive}" Value="False"> 
          <Setter Property="IsOpen" Value="False"/> 
         </DataTrigger> 
        </Style.Triggers> 
       </Style> 
      </Popup.Style> 
      <Border x:Name="errorBorder" 
      Background="#FFDC000C" 
      Margin="0,0,8,8" 
      Opacity="1" 
      CornerRadius="4" 
      IsHitTestVisible="False" 
      MinHeight="24" 
      MaxWidth="267"> 
       <Border.Effect> 
        <DropShadowEffect ShadowDepth="4" 
          Color="Black" 
          Opacity="0.6" 
          Direction="315" 
          BlurRadius="4"/> 
       </Border.Effect> 
       <TextBlock Text="{Binding ElementName=adorner, Path=AdornedElement.(Validation.Errors).CurrentItem.ErrorContent}" 
       Foreground="White" 
       Margin="8,3,8,3" 
       TextWrapping="Wrap"/> 
      </Border> 
     </Popup> 
    </StackPanel> 
</ControlTemplate> 

素晴らしいアイデア、特にその部分のスタイル

<Style TargetType="{x:Type TextBox}"> 
    <Setter Property="Validation.ErrorTemplate" Value="{StaticResource TextBoxErrorTemplate}"/> 
</Style> 
+0

私は、WPFの単純な問題に対する解決策の冗長さに常に驚いています。私だけでしょうか?私はコードのいくつかの行(10トップ)だけでJavaでこれを解決する方法を考えることができます。 MVVMとWPFはコードページです。 –

+0

これで問題が解決するかどうか調べるのに時間がかかります。私はいくつかの作業の後に更新します。ありがとうございました。 –

+0

@ÁrniSt.Sigurðssonだから...助けましたか? –

関連する問題