2016-11-04 25 views
1

既定のBorderBrushを持つWPF TextBoxがあります。テキストボックスに空のコンテンツがある場合、BorderBrushを赤色で変更したいと思います。ここに私のコードは次のとおりです。TextBoxテキストが変更された後にBorderBrushが更新されない

<TextBox Width="200" Text="{Binding Path=Description}" Name="tbDescription" Grid.Row="1" Grid.Column="2" Margin="2" 
          BorderBrush="{Binding RelativeSource={RelativeSource Self}, 
          Path=Text, 
          Converter={StaticResource borderBrushColorConverter}}"> 

そして、ここでは私のコンバータです:

public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
     { 
      string text = value as string; 

      if (string.IsNullOrEmpty(text)) 
       return Brushes.Red; 

      return Brushes.Transparent; 
     } 

     public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
     { 
      throw new NotImplementedException(); 
     } 

問題は国境がTextBoxのフォーカスが失われた場合にのみ、赤くなることです。 BorderBrushの代わりにBackgroundプロパティで同じコードを使用しようとしましたが、すべて正常に動作します。

+0

問題は、デフォルトでは、フォーカスが当てられたときにWPFがテキストボックスの周囲に青い枠線を追加するという問題です。その境界を削除する方法を探してみる必要があります。このリンクを試してください:(http://stackoverflow.com/questions/6404059/remove-default-mouseover-focus-effect-on-textboxes-in-wpf) –

+1

バインディングモードを「PropertyChanged」に変更すると機能しますかデフォルトの 'LostFocus'の? 'Text =" {バインディングパス=説明、Mode = PropertyChanged} " – Rachel

+1

ここでコンバーターを使わないで' DataTrigger'で 'Style'を作ってください。 – dymanoid

答えて

1

あなたはスタイルTempalte、これを試すことができます。

<TextBox BorderBrush="{Binding RelativeSource={RelativeSource Self}, 
         Path=Text, 
         Converter={StaticResource borderBrushColorConverter}}"> 
     <TextBox.Style> 
      <Style TargetType="{x:Type TextBox}"> 
       <Setter Property="Template"> 
        <Setter.Value> 
         <ControlTemplate TargetType="{x:Type TextBox}"> 
          <Border x:Name="Bd" 
            SnapsToDevicePixels="true" 
            Background="{TemplateBinding Background}" 
            BorderBrush="{TemplateBinding BorderBrush }" 
            BorderThickness="{TemplateBinding BorderThickness}" 
            Width="{TemplateBinding Width}" 
            Height="{TemplateBinding Height}"> 
           <ScrollViewer x:Name="PART_ContentHost"></ScrollViewer> 
          </Border> 
         </ControlTemplate> 
        </Setter.Value> 
       </Setter> 
      </Style> 
     </TextBox.Style> 
    </TextBox> 
1

たぶん、あなたが解決しようとしている問題は、単なる条件付きスタイリングのが、データ検証の一つではありません。その場合は、ビューモデルにIDataErrorInfoまたは-even better-INotifyDataErrorInfoのサポートを追加することを検討する価値があります。ここ

ごとのプロパティエラーストアとしてビューの各プロパティの変更後に実行されますValidate法に基づくモデル、及びDictionary<string, List<string>>に後者の可能な実装を次の

public class MyViewModel : INotifyPropertyChanged, INotifyDataErrorInfo 
{ 
    public string Description 
    { 
     get { return _description; } 

     set 
     { 
      _description = value; 
      NotifyPropertyChanged(); 
      Validate(); 
     } 
    } 

    private string _description; 

    private void Validate() 
    { 
     Errors[nameof(Description)].Clear(); 

     if (string.IsNullOrEmpty(Description)) 
     { 
      Errors[nameof(Description)].Add("The text cannot be empty"); 
     } 

     if (Errors[nameof(Description)].Any()) 
     { 
      NotifyErrorsChanged(nameof(Description)); 
     } 
    } 

    public IEnumerable GetErrors(string propertyName) 
     => Errors.ContainsKey(propertyName) ? Errors[propertyName] : Enumerable.Empty<string>(); 

    public bool HasErrors 
     => Errors.Any(propertyErrors => (propertyErrors.Value ?? Enumerable.Empty<string>()).Any()); 

    public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged; 

    protected virtual void NotifyErrorsChanged([CallerMemberName] string propertyName = null) 
     => ErrorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(propertyName)); 

    private IDictionary<string, List<string>> Errors { get; } 
     = new Dictionary<string, List<string>> 
     { 
      {nameof(Description), new List<string>()} 
     }; 

    public event PropertyChangedEventHandler PropertyChanged; 

    protected virtual void NotifyPropertyChanged([CallerMemberName] string propertyName = null) 
     => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); 
} 

ビュー側

関連する問題