【问题标题】:WPF TextBlock Negative Number In RedWPF TextBlock 负数为红色
【发布时间】:2011-03-13 09:59:57
【问题描述】:

我正在尝试找出创建样式/触发器以将前景设置为红色的最佳方法,当值

【问题讨论】:

    标签: wpf triggers styles textblock datatrigger


    【解决方案1】:

    如果您不使用 MVVM 模型(其中可能有 ForegroundColor 属性),那么最简单的做法是创建一个新的 IValueConverter,将您的背景绑定到您的值。

    在 MyWindow.xaml 中:

    <Window ...
        xmlns:local="clr-namespace:MyLocalNamespace">
        <Window.Resources>
            <local:ValueToForegroundColorConverter x:Key="valueToForeground" />
        <Window.Resources>
    
        <TextBlock Text="{Binding MyValue}"
                   Foreground="{Binding MyValue, Converter={StaticResource valueToForeground}}" />
    </Window>
    

    ValueToForegroundColorConverter.cs

    using System;
    using System.Windows.Media;
    using System.Windows.Data;
    
    namespace MyLocalNamespace
    {
        class ValueToForegroundColorConverter: IValueConverter
        {
            #region IValueConverter Members
    
            public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
            {
                SolidColorBrush brush = new SolidColorBrush(Colors.Black);
    
                Double doubleValue = 0.0;
                Double.TryParse(value.ToString(), out doubleValue);
    
                if (doubleValue < 0)
                    brush = new SolidColorBrush(Colors.Red);
    
                return brush;
            }
    
            public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
            {
                throw new NotImplementedException();
            }
    
            #endregion
        }
    }
    

    【讨论】:

    • @LnDCobra:它将与 MVVM 一起使用。我认为 Wonko 的意思是,使用 MVVM,您可以选择在视图模型上公开 ForegroundColor 属性,而不是使用 ValueConverter。
    • @Jakob:绝对正确。 @LnDCobra:您可以实现一个样式,将 Foreground 属性的值设置为与上面相同的绑定。
    • 一个更灵活的解决方案是使用一个转换器来确定一个值是否
    • 是的,这是真的。我只是按照问题的上下文进行,返回颜色似乎“足够好”。这只是一个简单的解决方案,当然可以根据需要进行扩展——足以“开始”。正如您所指出的,添加触发器只是又一步。
    • @WonkotheSane Foreground="{Binding MyValue, Converter={StaticResource valueToBackground}}" /&gt; 这应该是Foreground="{Binding MyValue, Converter={StaticResource valueToForeground}}" /&gt;
    【解决方案2】:

    您的 ViewModel 中应该有您的视图特定信息。但是你可以去掉 ViewModel 中的 Style 特定信息。

    因此在 ViewModel 中创建一个返回布尔值的属性

    public bool IsMyValueNegative { get { return (MyValue < 0); } }
    

    并在 DataTrigger 中使用它,这样您就可以消除 ValueConverter 及其装箱/拆箱。

    <TextBlock Text="{Binding MyValue}"> 
      <TextBlock.Style> 
        <Style> 
          <Style.Triggers> 
            <DataTrigger Binding="{Binding IsMyValueNegative}" Value="True"> 
              <Setter Property="Foreground" Value="Red" /> 
            </DataTrigger> 
          </Style.Triggers> 
        </Style> 
      </TextBlock.Style> 
    </TextBlock> 
    

    【讨论】:

    • 同意这样会更好。最初的答案源于他没有提到他正在使用 MVVM,而问题暗示(对我来说)他没有。
    • 这可行,但我不想这样做的原因是,对于每个 TextBlock,我需要为每个文本块设置一个单独的属性(每个视图通常 10+)
    • 只是关于命名约定的一点点​​。我的应用程序充满了这种 xaml hack,我发现按目的命名它们更容易。即: public bool DisplayBasketValueInRed { get;放; }。我还使用(尽管可能不应该)一个通用类来减少在这些属性上实现 INotifyPropertyChanged 的​​冗长程度。
    • @LnDCobra 我也有针对这些场景的特殊解决方案。转换器太冗长,或者在视图之外没有任何重用,并且属性使 ViewModel 冗长......所以我将我的值绑定到 TextBlock.DataContext 而不是 TextBlock.Text。然后编写一个通用(转换发送者)DataContextChanged 事件,该事件可应用于每个Textblock
    【解决方案3】:

    对于 Amsakanna 的解决方案,我必须向 Property Setter 添加一个类名:

    【讨论】:

    • 这是因为样式应该定义 TargetType:
    猜你喜欢
    • 2015-01-09
    • 2010-10-12
    • 1970-01-01
    • 2019-02-15
    • 2019-01-27
    • 2011-07-28
    • 2013-06-21
    • 2021-09-16
    • 1970-01-01
    相关资源
    最近更新 更多