如何更改TextBlock';s背景颜色(如果字符串值不相等)
本文关键字:如果 字符串 不相等 颜色 背景 TextBlock 何更改 | 更新日期: 2023-09-27 18:24:08
我有一个UserControl,它只存在两个TextBlock:
<UserControl [...] x:Name="root">
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding Text1, ElementName=root}" />
<TextBlock Text="{Binding Text2, ElementName=root}" />
</StackPanel>
</UserControl>
后面的相应代码如下所示:
public static readonly DependencyProperty Text1Property = DependencyProperty.Register("Text1", typeof(String), typeof(CmpText));
public static readonly DependencyProperty Text2Property = DependencyProperty.Register("Text2", typeof(String), typeof(CmpText));
public string Text1
{
get { return (string)GetValue(Text1Property); }
set { SetValue(Text1Property, value); }
}
public string Text2
{
get { return (string)GetValue(Text2Property); }
set { SetValue(Text2Property, value); }
}
这就是我在MainWindow.xml中使用UserControl的方式:
<local:CmpText Text1="{Binding Password1}" Text2="{Binding Password2}" />
如果Text1和Text2都不相等,我基本上想要的是第二个TextBlock的背景将其颜色更改为红色。
我试图在代码后面使用一个helper属性:
public bool IsEqual { get { return Text1 == Text2; } }
并将第二个TextBlock的样式设置为
<Style TargetType="{x:Type TextBlock}">
<Style.Triggers>
<DataTrigger Binding="{Binding IsEqual, ElementName=root}" Value="True">
<Setter Property="Background" Value="Red"/>
</DataTrigger>
</Style.Triggers>
</Style>
然而,即使Text1&文本2属性不匹配。我认为我的助手属性"IsEqual"比较了Text1&Text2,恰好为NULL(我无法确认,因为我无法调试GUI)。因此,IsEqual的评估似乎是在我的文本属性被分配任何值之前进行的。我希望在分配文本属性后进行评估。
我不知道该怎么办。你能帮忙吗?
目前WPF无法发现IsEqual
已更改,因此不会重新评估绑定。
你可以做三件事:
-
使
IsEqual
成为另一个依赖属性,并将PropertyChangedCallbacks添加到Text1
和Text2
,无论它们何时更改,都会更新IsEqual
。 -
或者,在
Text1
和Text2
PropertyChangedCallbacks中实现INotifyPropertyChanged并引发IsEqual
的PropertyChanged事件。 -
或者,将MultiBinding与IMultiValueConverter结合使用,将Background属性直接绑定到
Text1
和Text2
。转换器将获得两个字符串作为输入并返回一个Brush。
您可以在`WPF
中调试UI,即使它不像通常的.NET
应用程序那样直接。在绑定中,仅出于调试目的,例如添加一个Converter
。还有其他方法可以确定binding
发生了什么。
查看有关如何调试的提示,并了解WPF优秀的Josh Smith的文章。
使用此功能,查看:
- 如果您的
Text1
和Text2
属性实际上是通过您分配给它们的值获得的 - 如果有yes/no,则在某些情况下可能不会发生:例如,您需要按
TAB
来散焦,因此运行绑定
至少检查一下这一点,你应该已经能够提出一些想法了。
希望这能有所帮助。
首先,确保用作DataContext的对象(具有Password1和Password2属性)实现属性的INotifyPropertyChanged
接口。
要实现这样的行为,可以使用依赖属性回调和验证:当UserControl的Text1或Text2属性更改时,需要强制(重新计算)IsEqual属性。
以下是实现:
public partial class CmpTextView : UserControl
{
public CmpTextView()
{
InitializeComponent();
}
private static readonly DependencyPropertyKey IsEqualPropertyKey = DependencyProperty.RegisterReadOnly("IsEqual", typeof(bool), typeof(CmpTextView), new FrameworkPropertyMetadata(null, CoerceIsEqual));
public static readonly DependencyProperty IsEqualProperty = IsEqualPropertyKey.DependencyProperty;
public bool IsEqual
{
get { return (bool)GetValue(IsEqualProperty); }
}
private static object CoerceIsEqual(DependencyObject d, object baseValue)
{
CmpTextView cmpTextView = (CmpTextView) d;
return cmpTextView.Text1 == cmpTextView.Text2;
}
public static readonly DependencyProperty Text1Property = DependencyProperty.Register("Text1", typeof(String), typeof(CmpTextView), new FrameworkPropertyMetadata(OnTextChanged));
public string Text1
{
get { return (string)GetValue(Text1Property); }
set { SetValue(Text1Property, value); }
}
public static readonly DependencyProperty Text2Property = DependencyProperty.Register("Text2", typeof(String), typeof(CmpTextView), new FrameworkPropertyMetadata(OnTextChanged));
public string Text2
{
get { return (string)GetValue(Text2Property); }
set { SetValue(Text2Property, value); }
}
private static void OnTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
d.CoerceValue(IsEqualProperty);
}
}
希望能有所帮助。