动态资源数据触发检查值

发布于 2025-01-11 07:32:37 字数 2224 浏览 0 评论 0原文

我有一个 WPF 应用程序,其内容应以德语和英语显示。因此,我创建了两个单独的资源字典,其中包含每种语言的字符串片段。应用程序运行时可以在语言之间切换。 此时我遇到了一个问题。用户可以进行一些设置。如果设置成功完成,则会显示一条消息。消息的文本取自资源字典。根据成功或错误消息,文本显示为绿色或红色。

<TextBlock Text="{Binding UpdateTaxPercentageSettingsMessage}" FontWeight="Bold">
    <TextBlock.Style>
        <Style TargetType="{x:Type TextBlock}">
            <Style.Triggers>
                <DataTrigger Binding="{Binding UpdateTaxPercentageSettingsMessage}" Value="{DynamicResource tax_percentage_update_went_wrong}">
                    <Setter Property="Foreground" Value="Red"/>
                </DataTrigger>
                <DataTrigger Binding="{Binding UpdateTaxPercentageSettingsMessage}" Value="{StaticResource active_tax_law_update_went_wrong}">
                    <Setter Property="Foreground" Value="Red"/>
                </DataTrigger>
                <DataTrigger Binding="{Binding UpdateTaxPercentageSettingsMessage}" Value="{StaticResource tax_percentage_was_updated_successfully}">
                    <Setter Property="Foreground" Value="Green"/>
                </DataTrigger>
                <DataTrigger Binding="{Binding UpdateTaxPercentageSettingsMessage}" Value="{StaticResource active_tax_law_was_updated_successfully}">
                    <Setter Property="Foreground" Value="Green"/>
                </DataTrigger>
                <DataTrigger Binding="{Binding UpdateTaxPercentageSettingsMessage}" Value="{StaticResource differential_taxation_info_update_went_wrong}">
                    <Setter Property="Foreground" Value="Red"/>
                </DataTrigger>
                <DataTrigger Binding="{Binding UpdateTaxPercentageSettingsMessage}" Value="{StaticResource differential_taxation_info_was_updated_successfully}">
                    <Setter Property="Foreground" Value="Green"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </TextBlock.Style>
</TextBlock>

为了能够在应用程序运行时切换语言,从资源字典中获取的字符串片段必须是DynamicResource。不幸的是,我无法使用DynamicResource作为数据触发器中的条件。有人遇到过类似的问题吗?我很感谢您的建议!

I have a WPF application and the content of should be displayed in German and English. Therefore, I created two seperate resource dictionaries which contain string snippets in each language. It is possible to switch between the languages while the application is running.
At this point I got stuck at a problem. There are some settings the user can make. If the setting was completed successfully a message shows up. The text of the message is taken from the resource dictionary. Based on a success or error message the text is displayed green or red.

<TextBlock Text="{Binding UpdateTaxPercentageSettingsMessage}" FontWeight="Bold">
    <TextBlock.Style>
        <Style TargetType="{x:Type TextBlock}">
            <Style.Triggers>
                <DataTrigger Binding="{Binding UpdateTaxPercentageSettingsMessage}" Value="{DynamicResource tax_percentage_update_went_wrong}">
                    <Setter Property="Foreground" Value="Red"/>
                </DataTrigger>
                <DataTrigger Binding="{Binding UpdateTaxPercentageSettingsMessage}" Value="{StaticResource active_tax_law_update_went_wrong}">
                    <Setter Property="Foreground" Value="Red"/>
                </DataTrigger>
                <DataTrigger Binding="{Binding UpdateTaxPercentageSettingsMessage}" Value="{StaticResource tax_percentage_was_updated_successfully}">
                    <Setter Property="Foreground" Value="Green"/>
                </DataTrigger>
                <DataTrigger Binding="{Binding UpdateTaxPercentageSettingsMessage}" Value="{StaticResource active_tax_law_was_updated_successfully}">
                    <Setter Property="Foreground" Value="Green"/>
                </DataTrigger>
                <DataTrigger Binding="{Binding UpdateTaxPercentageSettingsMessage}" Value="{StaticResource differential_taxation_info_update_went_wrong}">
                    <Setter Property="Foreground" Value="Red"/>
                </DataTrigger>
                <DataTrigger Binding="{Binding UpdateTaxPercentageSettingsMessage}" Value="{StaticResource differential_taxation_info_was_updated_successfully}">
                    <Setter Property="Foreground" Value="Green"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </TextBlock.Style>
</TextBlock>

To make switching languages possible while the application is running, the string snippets taken from the resource dictionary has to be a DynamicResource. Unfortunately, I can not use DynamicResources as condition in data triggers. Has anyone faced a similar problem yet? I am grateful for your suggestions!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

不必你懂 2025-01-18 07:32:37

不要对本地化文本使用触发器,它也不能与 DynamicResouce 一起使用,因为 Value 不是依赖属性,也不可读。相反,创建一个描述您的错误的枚举

public enum ErrorType
{
   WhoCares, // No comment on this.
   ThisIsSuspicious, // Suspicous value.
   ItsATrap, // Admiral Ackbar warned us.
   ItIsNotWhatYouThinkItIs, // It is exactly what you think.
   ItCannotBeThatSerious, // Serious Sam approves.
   WhatDoesTheFlashingRedLightMean // If it is still flashing, how bad can it be, really?
}

公开错误的另一个属性,并在必要时实现 INotifyPropertyChanged 。

public ErrorType ErrorType { get; } 

使用属性而不是您的资源作为触发器的Value

<TextBlock Text="{Binding UpdateTaxPercentageSettingsMessage}" FontWeight="Bold">
   <TextBlock.Style>
      <Style TargetType="{x:Type TextBlock}">
         <Style.Triggers>
            <DataTrigger Binding="{Binding ErrorType}" Value="{x:Static local:ErrorType.WhoCares}">
               <Setter Property="Foreground" Value="Red"/>
            </DataTrigger>
            <DataTrigger Binding="{Binding ErrorType}" Value="{x:Static local:ErrorType.ThisIsSuspicious}">
               <Setter Property="Foreground" Value="Red"/>
            </DataTrigger>
            <DataTrigger Binding="{Binding ErrorType}" Value="{x:Static local:ErrorType.ItsATrap}">
               <Setter Property="Foreground" Value="Green"/>
            </DataTrigger>
            <DataTrigger Binding="{Binding ErrorType}" Value="{x:Static local:ErrorType.ItIsNotWhatYouThinkItIs}">
               <Setter Property="Foreground" Value="Green"/>
            </DataTrigger>
            <DataTrigger Binding="{Binding ErrorType}" Value="{x:Static local:ErrorType.ItCannotBeThatSerious}">
               <Setter Property="Foreground" Value="Red"/>
            </DataTrigger>
            <DataTrigger Binding="{Binding ErrorType}" Value="{x:Static local:ErrorType.WhatDoesTheFlashingRedLightMean}">
               <Setter Property="Foreground" Value="Green"/>
            </DataTrigger>
         </Style.Triggers>
      </Style>
   </TextBlock.Style>
</TextBlock>

奖励回合。由于您的数据触发器是重复的(它们经常设置相同的值),请考虑使用带有自定义转换器的绑定,该转换器简单地说,如果绑定值与任何给定的值,应用此设置器。

public class IsMatchingConverter : IValueConverter
{
   public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
   {
      if (!(parameter is IEnumerable enumerable))
         return false;

      return enumerable.Cast<object>().Contains(value);
   }

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

在范围内的任何资源字典中创建转换器的实例。

<Window.Resources>
   <local:IsMatchingConverter x:Key="IsMatchingConverter"/>
</Window.Resources>

更改数据触发器并将数组中的目标值作为转换器参数传递。

<TextBlock Text="{Binding UpdateTaxPercentageSettingsMessage}" FontWeight="Bold">
   <TextBlock.Style>
      <Style TargetType="{x:Type TextBlock}">
         <Style.Triggers>
            <DataTrigger Value="True">
               <DataTrigger.Binding>
                  <Binding Path="ErrorType" Converter="{StaticResource IsMatchingConverter}">
                     <Binding.ConverterParameter>
                        <x:Array Type="local:ErrorType">
                           <local:ErrorType>WhoCares</local:ErrorType>
                           <local:ErrorType>ThisIsSuspicious</local:ErrorType>
                           <local:ErrorType>ItCannotBeThatSerious</local:ErrorType>
                        </x:Array>
                     </Binding.ConverterParameter>
                  </Binding>
               </DataTrigger.Binding>
               <Setter Property="Foreground" Value="Red"/>
            </DataTrigger>
            <DataTrigger Value="True">
               <DataTrigger.Binding>
                  <Binding Path="ErrorType" Converter="{StaticResource IsMatchingConverter}">
                     <Binding.ConverterParameter>
                        <x:Array Type="local:ErrorType">
                           <local:ErrorType>ItsATrap</local:ErrorType>
                           <local:ErrorType>ItIsNotWhatYouThinkItIs</local:ErrorType>
                           <local:ErrorType>WhatDoesTheFlashingRedLightMean</local:ErrorType>
                        </x:Array>
                     </Binding.ConverterParameter>
                  </Binding>
               </DataTrigger.Binding>
               <Setter Property="Foreground" Value="Green"/>
            </DataTrigger>
         </Style.Triggers>
      </Style>
   </TextBlock.Style>
</TextBlock>

Do not use triggers on localized text, neither does it work with DynamicResouce, because Value is not a dependency property, nor is it readable. Instead, create an enum that describes your errors.

public enum ErrorType
{
   WhoCares, // No comment on this.
   ThisIsSuspicious, // Suspicous value.
   ItsATrap, // Admiral Ackbar warned us.
   ItIsNotWhatYouThinkItIs, // It is exactly what you think.
   ItCannotBeThatSerious, // Serious Sam approves.
   WhatDoesTheFlashingRedLightMean // If it is still flashing, how bad can it be, really?
}

Expose anothe property for the error and implement INotifyPropertyChanged if necessary.

public ErrorType ErrorType { get; } 

Use the property instead of your resources as Value of the triggers.

<TextBlock Text="{Binding UpdateTaxPercentageSettingsMessage}" FontWeight="Bold">
   <TextBlock.Style>
      <Style TargetType="{x:Type TextBlock}">
         <Style.Triggers>
            <DataTrigger Binding="{Binding ErrorType}" Value="{x:Static local:ErrorType.WhoCares}">
               <Setter Property="Foreground" Value="Red"/>
            </DataTrigger>
            <DataTrigger Binding="{Binding ErrorType}" Value="{x:Static local:ErrorType.ThisIsSuspicious}">
               <Setter Property="Foreground" Value="Red"/>
            </DataTrigger>
            <DataTrigger Binding="{Binding ErrorType}" Value="{x:Static local:ErrorType.ItsATrap}">
               <Setter Property="Foreground" Value="Green"/>
            </DataTrigger>
            <DataTrigger Binding="{Binding ErrorType}" Value="{x:Static local:ErrorType.ItIsNotWhatYouThinkItIs}">
               <Setter Property="Foreground" Value="Green"/>
            </DataTrigger>
            <DataTrigger Binding="{Binding ErrorType}" Value="{x:Static local:ErrorType.ItCannotBeThatSerious}">
               <Setter Property="Foreground" Value="Red"/>
            </DataTrigger>
            <DataTrigger Binding="{Binding ErrorType}" Value="{x:Static local:ErrorType.WhatDoesTheFlashingRedLightMean}">
               <Setter Property="Foreground" Value="Green"/>
            </DataTrigger>
         </Style.Triggers>
      </Style>
   </TextBlock.Style>
</TextBlock>

Bonus round. As your data triggers are repetitive (they set the same values often), consider using a Binding with a custom converter that simply says, if the bound value matches any of the given values, apply this setter.

public class IsMatchingConverter : IValueConverter
{
   public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
   {
      if (!(parameter is IEnumerable enumerable))
         return false;

      return enumerable.Cast<object>().Contains(value);
   }

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

Create an instance of the converter in any resource dictionary in scope.

<Window.Resources>
   <local:IsMatchingConverter x:Key="IsMatchingConverter"/>
</Window.Resources>

Change the data triggers and pass the target values in an array as converter parameters.

<TextBlock Text="{Binding UpdateTaxPercentageSettingsMessage}" FontWeight="Bold">
   <TextBlock.Style>
      <Style TargetType="{x:Type TextBlock}">
         <Style.Triggers>
            <DataTrigger Value="True">
               <DataTrigger.Binding>
                  <Binding Path="ErrorType" Converter="{StaticResource IsMatchingConverter}">
                     <Binding.ConverterParameter>
                        <x:Array Type="local:ErrorType">
                           <local:ErrorType>WhoCares</local:ErrorType>
                           <local:ErrorType>ThisIsSuspicious</local:ErrorType>
                           <local:ErrorType>ItCannotBeThatSerious</local:ErrorType>
                        </x:Array>
                     </Binding.ConverterParameter>
                  </Binding>
               </DataTrigger.Binding>
               <Setter Property="Foreground" Value="Red"/>
            </DataTrigger>
            <DataTrigger Value="True">
               <DataTrigger.Binding>
                  <Binding Path="ErrorType" Converter="{StaticResource IsMatchingConverter}">
                     <Binding.ConverterParameter>
                        <x:Array Type="local:ErrorType">
                           <local:ErrorType>ItsATrap</local:ErrorType>
                           <local:ErrorType>ItIsNotWhatYouThinkItIs</local:ErrorType>
                           <local:ErrorType>WhatDoesTheFlashingRedLightMean</local:ErrorType>
                        </x:Array>
                     </Binding.ConverterParameter>
                  </Binding>
               </DataTrigger.Binding>
               <Setter Property="Foreground" Value="Green"/>
            </DataTrigger>
         </Style.Triggers>
      </Style>
   </TextBlock.Style>
</TextBlock>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文