从转换器返回一个动态资源

10

我想根据布尔值的状态(在这种情况下是复选框的状态)来更改WPF控件的颜色,只要我使用StaticResources就可以正常工作:

我的控件

<TextBox Name="WarnStatusBox" TextWrapping="Wrap" Style="{DynamicResource StatusTextBox}" Width="72" Height="50" Background="{Binding ElementName=WarnStatusSource, Path=IsChecked, Converter={StaticResource BoolToWarningConverter}, ConverterParameter={RelativeSource self}}">Status</TextBox>

我的转换器:

[ValueConversion(typeof(bool), typeof(Brush))]

public class BoolToWarningConverter : IValueConverter
{
    public FrameworkElement FrameElem = new FrameworkElement();

    public object Convert(object value, Type targetType,
        object parameter, CultureInfo culture)
    {                      
        bool state = (bool)value;
        try
        {              
            if (state == true)
                return (FrameElem.TryFindResource("WarningColor") as Brush);
            else
                return (Brushes.Transparent);
        }

        catch (ResourceReferenceKeyNotFoundException)
        {
            return new SolidColorBrush(Colors.LightGray);
        }
    }

    public object ConvertBack(object value, Type targetType,
        object parameter, CultureInfo culture)
    {
        return null;
    }
}

问题在于我有几个资源“WarningColor”的定义,取决于是白天模式还是夜间模式。这些事件不会触发WarningColor的更改。是否有办法使返回值动态化,或者我需要重新考虑我的设计?


1
你能否在MultiBinding中使用IMultiValueConverter?我认为你有两个值应该触发更改,而不仅仅是IsChecked。 - Louis Kottmann
没错,那就是我最终做的。我不得不添加一个处理程序来捕获显示更新事件并更新可观察计数器。 - lewi
2个回答

3
您不能从转换器返回动态内容,但是如果您只有一个布尔条件,您可以使用触发器轻松地用样式替换整个转换器:

例如:

<Style TargetType="TextBox">
    <Setter Property="Background" Value="Transparent" />
    <Style.Triggers>
        <DataTrigger Binding="{Binding IsChecked, ElementName=WarnStatusSource}" Value="True">
            <Setter Property="Background" Value="{DynamicResource WarningColor}" />
        </DataTrigger>
    </Style.Triggers>
</Style>

如果现在这个关键字对应的资源被改变了,那么背景也应该相应地改变。

1
使用DynamicResourceExtension构造函数并提供资源键即可返回动态资源引用。
用法:
return new DynamicResourceExtension(Provider.ForegroundBrush);

Provider 类的定义应该包含以下关键内容:

public static ResourceKey ForegroundBrush 
{ 
    get 
    { 
        return new ComponentResourceKey(typeof(Provider), "ForegroundBrush"); 
    } 
}

键的值将在资源字典中声明:

<ResourceDictionary
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
     xmlns:theme="clr-namespace:Settings.Appearance;assembly=AppearanceSettingsProvider">

<Color x:Key="{ComponentResourceKey TypeInTargetAssembly={x:Type theme:Provider}, ResourceId=ForegroundColor}">#FF0000FF</Color>

<SolidColorBrush x:Key="{ComponentResourceKey {x:Type theme:Provider}, ForegroundBrush}" Color="{DynamicResource {ComponentResourceKey {x:Type theme:Provider}, ForegroundColor}}" />
</ResourceDictionary>

这样,转换器将根据提供的资源键动态地为绑定属性分配DynamicResource。

此外,使用 ComponentResource 不是必需的。您可以使用普通字符串键定义 DynamicResource。 - Chris Bordeman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接