【问题标题】:DataGridTextcolumn foreground datatrigger with stringfromat带有 stringfromat 的 DataGridTextcolumn 前景数据触发器
【发布时间】:2019-11-22 08:35:49
【问题描述】:

我想在 DataGridTextColumn 中以红色显示负货币,并在括号中显示负货币,例如 ($200.00)。 只要金额为负,我就可以使用转换器将前景转换为红色,如下面的 XAML 所示。 但是,当我尝试包含诸如 Binding="{Binding Path=NonTaxable, StringFormat=c2}" 之类的字符串格式时,前景色转换失败。

如何显示负货币

(a) 红色

(b) 在括号中

(c) 带有 $ 货币符号?

这里是 XAML 和代码。

<DataGridTextColumn Width="*" Header="NonTaxable" Binding="{Binding Path=NonTaxable}" >
   <DataGridTextColumn.ElementStyle>
      <Style TargetType="{x:Type TextBlock}">
          <Style.Triggers>
              <DataTrigger  Binding="{Binding RelativeSource={RelativeSource Self}, Path=Text, Converter={StaticResource NegativeValueConverter}}" Value="-1" >
                   <Setter Property="Foreground" Value="Red" />
             </DataTrigger>
          </Style.Triggers>
       </Style>
   </DataGridTextColumn.ElementStyle>               
</DataGridTextColumn>

VB.Net

Imports System.Globalization

Public Class NegativeValueConverter
    Implements IValueConverter

    Public Function Convert(value As Object, targetType As Type, parameter As Object, culture As CultureInfo) As Object Implements IValueConverter.Convert
        Dim doubleValue As [Double] = 0.0
        If value IsNot Nothing Then
            If [Double].TryParse(value.ToString(), doubleValue) Then
                If doubleValue < 0 Then
                    Return -1
                End If
            End If
        End If
        Return 1
    End Function

    Public Function ConvertBack(value As Object, targetType As Type, parameter As Object, culture As CultureInfo) As Object Implements IValueConverter.ConvertBack
        Throw New NotImplementedException()
    End Function

End Class

C#

using System.Globalization;

public class NegativeValueConverter : IValueConverter
{

    public object IValueConverter.Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        Double doubleValue = 0.0;
        if (value != null) {
            if (Double.TryParse(value.ToString(), doubleValue)) {
                if (doubleValue < 0) {
                    return -1;
                }
            }
        }
        return 1;
    }

    public object IValueConverter.ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }

}

【问题讨论】:

    标签: c# xaml


    【解决方案1】:

    编辑

    很抱歉误解了您的问题。

    它不起作用,因为您正在使用ElementStyle,并绑定到底层TetxBlockText 属性。应用StringFormat 后,您的转换器将不再工作,因为它将获得例如"($-200.00)" 而不是"200.0",然后Double.TryParse() 将失败并返回false。您可以相应地更改转换器(以使用格式化文本)或将触发器绑定到基础数据而不是格式化文本。

    例如,它将与CellStyle 一起使用,因为这样您就可以直接访问绑定的值。

    <DataGridTextColumn Width="*" Header="NonTaxable" Binding="{Binding Path=NonTaxable, StringFormat=(${0:0.00})}" >
        <DataGridTextColumn.CellStyle>
           <Style TargetType="DataGridCell">
               <Setter Property="Foreground" Value="Black"/>
               <Style.Triggers>
                   <DataTrigger Binding="{Binding Path=NonTaxable, Converter={StaticResource NegativeValueConverter}}" 
                           Value="-1" >
                        <Setter Property="Foreground" Value="Red" />
                    </DataTrigger>
                  </Style.Triggers>
                </Style>
             </DataGridTextColumn.CellStyle>
         </DataGridTextColumn>
      </DataGrid.Columns>
    </DataGrid>
    

    结束编辑


    您的StringFormat 将是:

    Binding="{Binding Path=NonTaxable, StringFormat=StringFormat=({0:C2})}"
    

    如果您的值将在格式化字符串中排在第一位,请记住在其前面加上一对括号,例如他的:

    Binding="{Binding Path=NonTaxable, StringFormat=StringFormat={}{0:C2}}"
    

    另外,请注意C2 格式是特定于文化的。始终注意应用程序中设置的语言,否则可能会出现意外格式。看看this StackOverflow question

    如果您想确保在您的情况下货币符号始终为$,那么明确设置格式可能会更好:

    Binding="{Binding Path=NonTaxable, StringFormat=StringFormat=(${0:0.00})}}"
    

    【讨论】:

    • 首先检测货币是否为负数,如果是则前景为红色。这就是为什么我使用了一个工作正常的转换器。之后,我想包含一个有效的货币符号,但只有当我不放置 StringFormat 时,DataTrigger 中的转换器才有效。它不能与 StringFormat 结合使用。
    • 问了一个类似的问题 (stackoverflow.com/questions/7492343/…)
    • @user10403352 对不起,我误解了你的问题。我编辑了我的答案。
    【解决方案2】:

    Arie 观察到的是真实的。在我看到 Arie 也观察到我所做的同样事情之前,我正要发布自己的答案。尽管如此,应该归功于 Arie。

    基本上,我想在 RED 和 BRACKET 中显示负货币。为此,我决定:

    (一)。以 Excel 的工作方式使用 StringFormat 进行绑定,即 Binding="{Binding Path=NonTaxable, StringFormat={}{0:$#,##0.00;($#,##0.00)}} 将负数转换为括号中的金额美元符号。

    (b) 将负货币放入括号后,我想用红色显示文本。我以为我可以使用 StringFormat={}{0:$#,##0.00;[Red]($#,##0.00) 在 Excel 中完成的方式,不幸的是无法完成在 XAML 中。因此我决定在 DataTrigger 中使用 Converter 并且颜色没有改变。

    挑战在于,如果我单独使用 StringFormat,它就可以工作。同样,DataTrigger 本身也可以工作。但是每当我结合 StringFormat 和 DataTrigger 时,DataTrigger 都不会触发。

    在挖掘和挖掘之后,我注意到 StringFormat 首先触发,然后是 DataTrigger。这很重要,因为这意味着当 DataTrigger 触发时,文本不再是数值,而是带有美元符号和括号的格式化文本(字符串)。因此,将此格式化的文本(字符串)发送到 DataTrigger 中的转换器不起作用,因为在转换器中,我正在检查数值是否

    简而言之,解决方案涉及如下修改转换器:

    正如 Arie 所说,在输入 say -8000 后,StringFormat 将此文本更改为 ($8,000.00)。因此,发送到转换器的不是 -8000,而是实际上($8,000.00)。通过使用 Replace 命令,必须将该字符串转换回 -8000,然后才能在转换器中进行任何检查。

    因此转换器应为:

    Public Function Convert(value As Object, targetType As Type, parameter As Object, culture As CultureInfo) As Object Implements IValueConverter.Convert
            Dim doubleValue As [Double] = 0.0
            If value IsNot Nothing Then
    
                Dim Input As String = TryCast(value, String)
                If Not String.IsNullOrEmpty(Input) Or
                        Not String.IsNullOrWhiteSpace(Input) Then
                    Input = Input.Replace("$", "")
                    Input = Input.Replace(" ", "")
                    Input = Input.Replace(",", "")
                    Input = Input.Replace(")", "")
                    Input = Input.Replace("(", "-")                
    
                    If [Double].TryParse(Input.ToString(), doubleValue) Then
    
                        If doubleValue < 0 Then
                            Return -1
                        End If
                    End If
                End If
    
            End If
            Return 1
        End Function
    

    也感谢 Arie 的回答。现在可以了。

    【讨论】:

      猜你喜欢
      • 2020-01-01
      • 1970-01-01
      • 2011-09-20
      • 1970-01-01
      • 1970-01-01
      • 2014-07-26
      • 2014-07-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多