2016-11-04 27 views
1

我有WPF文本框與默認BorderBrush。當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(); 
     } 

問題是,邊框變成紅色,只有當文本框焦點丟失。我試圖在背景屬性上使用相同的代碼,而不是在BorderBrush上,然後一切正常。

+0

問題是,默認情況下,WPF在焦點時在文本框周圍添加藍色邊框。您應該嘗試搜索一種方法來刪除該邊框。試試這個鏈接:(http://stackoverflow.com/questions/6404059/remove-default-mouseover-focus-effect-on-textboxes-in-wpf) –

+1

它是否工作,如果你改變你的綁定模式爲'PropertyChanged'默認的'Lo​​stFocus'? 'Text =「{綁定路徑=描述,模式= 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或更好的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)); 
} 

觀看側是減少到以下內容:

<TextBox Text="{Binding Description, Mode=TwoWay, ValidatesOnNotifyDataErrors=True, UpdateSourceTrigger=PropertyChanged}" />