如果字符串值不相等,如何更改TextBlock背景颜色?

时间:2012-02-10 19:21:37

标签: c# wpf binding

我有一个仅存在两个TextBlocks的UserControl:

<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}" />

我基本上想要的是第二个TextBlock的背景,如果Text1和Text2都不相等,它的颜色会变为红色。

我尝试在代码隐藏中使用辅助属性:

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>

然而,IsEqual总是变成'真'(并且TextBlock的背景总是红色),即使Text1&amp; Text2属性不匹配。我认为我的帮助属性'IsEqual'比较了Text1&amp;的默认值。 Text2,碰巧是NULL(我没有办法确认,因为我无法调试GUI)。因此,IsEqual的评估似乎在我的文本属性被赋予任何值之前发生。我希望评估在分配文本属性后发生。

我不知道该怎么办。你能帮忙吗?

3 个答案:

答案 0 :(得分:4)

目前,WPF无法发现IsEqual已发生变化,因此不会重新评估绑定。

你可以做三件事:

  1. 制作IsEqual另一个依赖项属性,并将PropertyChangedCallback添加到Text1Text2,无论何时更改,都会更新IsEqual。< / p>

  2. 或者,实施INotifyPropertyChanged并在IsEqualText1 PropertyChangedCallbacks中为Text2举起PropertyChanged事件。

  3. 或者,将MultiBindingIMultiValueConverter结合使用,将Background属性直接绑定到Text1Text2。转换器将获得两个字符串作为输入并返回一个Brush。

答案 1 :(得分:0)

可以在`WPF调试用户界面,即使它不像usula .NET应用程序那么简单。在绑定中,仅出于调试目的,例如添加Converter。 还有其他方法可以解决binding发生的事情。

查看Tips on how to debug and learn about WPF出色的Josh Smith的文章。

使用此功能,请查看:

  1. 如果您的Text1Text2属性实际上由您指定的值获得。
  2. 如果是/否,有一些情况可能没有发生:例如,您需要按TAB才能失去焦点,因此运行绑定。
  3. 至少检查一下,你已经能够提出一些想法。

    希望这有帮助。

答案 2 :(得分:0)

首先,确保用作DataContext的对象(具有Password1和Password2属性)为属性实现INotifyPropertyChanged接口。

要实现此类行为,您可以使用Dependency Property Callbacks and Validation:当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);
    }
}

希望它有所帮助。