WPF中的动态条件格式

时间:2015-01-09 14:57:59

标签: c# wpf xaml

我正在开发一个工程程序,它在VB.net中用一个单独的项目编写了所有计算,我们现在将它放在WPF UI之后。

我遇到了在单位之间更改字符串格式的问题。例如:在英制单位中,您的值为4,966 lbf,并将其转换为22.1 kN。您可以看到,2之间必须有不同的格式,因为它们是不同的数量级。

程序中当前设置的是条件着色(正常数字为黑色,错误为红色,警告为黄色),这些是通过资源字典中的样式设置的。

<Style x:Key="GlobalUserEditedTextBox" BasedOn="{StaticResource {x:Type TextBox}}" TargetType="TextBox">
     <Setter Property="Foreground" Value="{DynamicResource EditableTextColor}"/>
     <Setter Property="FontWeight" Value="Bold"/>
</Style>
<Style x:Key="GlobalErrorTextBox" BasedOn="{StaticResource {x:Type TextBox}}" TargetType="TextBox">
     <Setter Property="Foreground" Value="{DynamicResource ErrorTextColor}"/>
     <Setter Property="FontWeight" Value="Normal"/>
</Style>

在程序中,使用Converter和MultiBinding选择样式。 ValueShow.TensionStatusShow是来自VB计算代码的枚举值:

<TextBlock HorizontalAlignment="Stretch" TextAlignment="Center" Text="{Binding Path=ValueShow.TensionShow}">
    <TextBlock.Style>
        <MultiBinding Converter="{StaticResource styleConverter}">
            <MultiBinding.Bindings>
                <Binding RelativeSource="{RelativeSource Self}"/>
                <Binding Path="ValueShow.TensionStatusShow"/>
            </MultiBinding.Bindings>
        </MultiBinding>
    </TextBlock.Style>
</TextBlock>

然后是MultiValueConverter:

public class StyleConverter : IMultiValueConverter
    {
        public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            FrameworkElement targetElement = values[0] as FrameworkElement;
            Style _newStyle;
            try
            {
                if (values[1] == null || values[1] == DependencyProperty.UnsetValue)
                    return null;

                if ((String)values[1] == StatusColor.ErrorValue.ToString())
                {
                    if (values[0].GetType() == typeof(TextBox))
                        _newStyle = (Style)targetElement.TryFindResource("GlobalErrorTextBox");
                    else if (values[0].GetType() == typeof(TextBlock))
                        _newStyle = (Style)targetElement.TryFindResource("GlobalErrorTextBlock");
                    else
                        _newStyle = null;
                } 
                else if
                {
                    if (values[0].GetType() == typeof(TextBox))
                        _newStyle = (Style)targetElement.TryFindResource("GlobalWarningTextBox");
                    else if (values[0].GetType() == typeof(TextBlock))
                        _newStyle = (Style)targetElement.TryFindResource("GlobalWarningTextBlock");
                    else
                        _newStyle = null;
                }
                return _newStyle;
            }
            catch (Exception)
            {
                if (values[0].GetType() == typeof(TextBox))
                    return (Style)targetElement.TryFindResource("GlobalUnEditableTextBox");
                else if (values[0].GetType() == typeof(TextBlock))
                    return (Style)targetElement.TryFindResource("GlobalUnEditableTextBlock");
                else
                    return null;
            }
        }

我尝试了什么: 所以这里的问题是我想保持字符串格式化&#34;规则&#34;与ValueShow.TensionStatusShow不同的VB计算方法。目前,我们有2个资源字典(英制和公制),用于保存单位标签的字符串。我尝试在那里设置不同的字符串格式,以便在程序更改单位时更新。

帝国资源:

<s:String x:Key="UnitsStringFormatlbfkN">F0</s:String>
<Style TargetType="TextBox" x:Key="GlobalErrorTextBoxlbkNFormatting" BasedOn="{StaticResource GlobalErrorTextBox}">
        <Setter Property="Text" Value="{Binding Path=., Mode=TwoWay, StringFormat={StaticResource UnitsStringFormatlbfkN}}" />
    </Style>

指标资源

<s:String x:Key="UnitsStringFormatlbfkN">F1</s:String>
<Style TargetType="TextBox" x:Key="GlobalErrorTextBoxlbkNFormatting" BasedOn="{StaticResource GlobalErrorTextBox}">
        <Setter Property="Text" Value="{Binding Path=., Mode=TwoWay, StringFormat={StaticResource UnitsStringFormatlbfkN}}" />
    </Style>

然后我将lbkNFormatting作为多重绑定中的第三个参数传递,并将其附加到TryFindResource调用。这显然没有用,它会成功加载资源但忽略了字符串格式。我通过向Metric资源添加背景颜色进行测试,该资源加载得很好,但同样,字符串格式被忽略了。

我还尝试通过以编程方式添加字符串格式来修改MultiValueConverter中的样式,但遇到IsSealed属性,我似乎无法打败

1 个答案:

答案 0 :(得分:2)

很抱歉快速和短暂而且没有完整和间接的回复,但我想给你一个经常被忽视的解决方案。当有些绑定或样式变得太复杂并且开始失败并且似乎无法追踪原因时,或者当我看到我可以从额外的解耦中受益时,我有时会使用它。

几乎所有样式,触发器和复杂绑定+ MultiValueCoverters,您都可以重写为所谓的&#34;附加行为&#34;。

See this article快速浏览一下。请注意两种方式,附加属性和额外子元素。

实际上,我喜欢同时使用两者中最好的一个。由于我想给你留言,我已经修剪了这个答案并将健谈的文字移到了this article

我知道这并没有回答你关于Style&amp; Binding为什么不起作用的问题,但我仍然认为你会发现它有用。你的样式和绑定看起来很复杂,难以调试,我现在无法专注于:|问题是,通过尝试将值放在错误的范围/级别上,绑定可以很容易地被破坏(分离,覆盖),甚至样式和触发器中的setter也可以取消它们与目标的链接。我觉得这就是正在发生的事情,但我不会有更多的时间来帮助你在不久的将来追踪它。所以..祝你好运,我希望有人设法给你一个更好的回应。