簡體   English   中英

WPF中的動態條件格式

[英]Dynamic Conditional Formatting in WPF

我正在研究一個工程程序,它在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;
            }
        }

我試過的:所以這里的問題是我想保持字符串格式化“規則”不包括在VB計算方法中,這與ValueShow.TensionStatusShow不同。 目前,我們有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作為lbkNFormatting中的第三個參數傳遞,並將其附加到TryFindResource調用。 這顯然不起作用,它會成功加載資源,但它忽略了字符串格式。 我通過向Metric資源添加背景顏色進行測試,該資源加載得很好,但同樣,字符串格式被忽略了。

我也嘗試通過以編程方式添加字符串格式來修改MultiValueConverter中的樣式但是遇到了IsSealed屬性,我似乎無法擊敗

對不起快速和簡短而不是完整和間接的回復,但我想給你一個經常被忽視的解決方案。 當有些綁定或樣式變得太復雜並且開始失敗並且似乎無法追蹤原因時,或者當我看到我可以從額外的解耦中受益時,我有時會使用它。

幾乎所有樣式,觸發器和復雜綁定+ MultiValueCoverters,您都可以重寫為所謂的“附加行為”。

有關快速瀏覽, 請參閱此文章 請注意兩種方式,附加屬性和額外子元素。

實際上,我喜歡同時使用兩者中最好的。 因為我想給你留言,我已經修剪了這個答案,並將健談的文字移到了這篇文章中

我知道這不能回答你關於為什么Style&Binding不起作用的問題,但我仍然認為你可能會發現它有用。 你的樣式和綁定看起來很復雜,難以調試,我現在無法專注於:| 問題是,通過嘗試將值放在錯誤的范圍/級別上,綁定可以很容易地被破壞(分離,覆蓋),甚至樣式和觸發器中的setter也可以取消它們與目標的鏈接。 我感覺這就是正在發生的事情,但我將沒有更多的時間來幫助你在不久的將來追蹤它。 所以..祝你好運,我希望有人設法給你一個更好的回應。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM