我有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焦点丢失时,边框才会变红。我尝试在Background属性上使用相同的代码而不是BorderBrush,然后一切正常。
答案 0 :(得分: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 :(得分: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}" />