2016-11-04 5 views
1

기본 BorderBrush가있는 WPF TextBox가 있습니다. 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 대신 Background 속성에서 같은 코드를 사용하려고했는데 모든 것이 잘 동작합니다.

+0

기본적으로 WPF는 포커스가있을 때 텍스트 상자 주위에 파란색 테두리를 추가합니다. 경계를 제거하는 방법을 찾아보십시오. 이 링크를보십시오 : (http://stackoverflow.com/questions/6404059/remove-default-mouseover-focus-effect-on-textboxes-in-wpf) –

+1

바인딩 모드를 대신 'PropertyChanged'로 변경하면 작동합니까? 기본 'LostFocus'? 'Text = "{Binding Path = Description, 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 또는 -venven-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)); 
} 

보기 쪽

관련 문제