C# 将属性绑定到视图的样式/资源字典

C# 将属性绑定到视图的样式/资源字典,c#,wpf,caliburn.micro,C#,Wpf,Caliburn.micro,我的一个视图由5个UserControls组成,每个控件都显示关于某个对象的数据。例如,让我们假设视图显示我们公司拥有的奶牛,并且在屏幕上显示奶牛1到5(每个奶牛都有自己的用户控件) 我想做的(但不确定是否可能)是将cow的状态绑定到其各自的UserControl中使用的样式。例如,我们有一个属性status,它可能是ok,饥饿,死亡。如果奶牛正常我希望显示“正常”样式,如果奶牛饥饿我希望背景为红色,如果奶牛死亡我希望文本为黑色,字体大小增加 我已经添加了一个简化版本,以实现我的目标。不过,我对

我的一个视图由5个
UserControls
组成,每个控件都显示关于某个对象的数据。例如,让我们假设视图显示我们公司拥有的奶牛,并且在屏幕上显示奶牛1到5(每个奶牛都有自己的用户控件)

我想做的(但不确定是否可能)是将cow的状态绑定到其各自的UserControl中使用的样式。例如,我们有一个属性
status
,它可能是
ok
饥饿
死亡
。如果奶牛
正常
我希望显示“正常”样式,如果奶牛
饥饿
我希望背景为红色,如果奶牛
死亡
我希望文本为黑色,字体大小增加

我已经添加了一个简化版本,以实现我的目标。不过,我对WPF样式/资源字典的了解还是有点有限

我基本上想要的代码 具有
状态
属性的ViewModel

class CowInfoViewModel : Screen
{
    public string Name { get; set; }

    public string Status { get; set; } //"ok", "hungry", "dead"
}
检索样式或资源字典的视图

<UserControl x:Class="WpfModifyDifferentView.Views.CowInfoView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <!-- A reference to a ResourceDictionary with styles, that is bound to the 'Status' property -->

    <StackPanel>
        <TextBlock x:Name="Name" Text="Cow Name"/>
        <TextBlock x:Name="Status" Text="Ok" />
    </StackPanel>
</UserControl>
然后,我创建了多个ResourceDictionary,其样式如下:

<Style x:Key="TextBlockCowName" TargetType="TextBlock">
    <Setter Property="Foreground" Value="{StaticResource SomeBrush}" />
</Style>

您可以将UserControl样式属性绑定到状态并使用转换器

<UserControl x:Class="WpfModifyDifferentView.Views.CowInfoView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
             xmlns:local="clr-namespace:WpfModifyDifferentView"
             Style="{Binding Path=Status, Converter={StaticResource myConverter}}">
        <UserControl.Resources>
            <local:MyConverter x:Key="myConverter" />
        </UserControl.Resources>

当然,您需要指定正确的URI。

谢谢您的回答:)此时我工作的地方出现了一些其他问题。我将再次尝试这个方法,我只是尝试了一下,效果很好:)我只是想知道是否有可能更改多个元素的样式?(对于某些特定元素,样式总是有一个
TargetType
,对吗?)例如,我想升级UserControl、网格、边框和文本块,但是(afaik)每个元素都需要一个不同的样式元素。这是否意味着我必须在
状态
案例中有一个额外的switch语句才能获得元素各自的样式?是的,如果您要针对该类型执行特定操作,则需要使用不同的样式。但如果要更改常规(基本)属性,可以将TargetType设置为Control或FrameworkElement,例如。是的,如果您想在具有不同样式的不同类型上使用相同的转换程序,可以在ADION to switch语句中检查targetType参数。通过在xaml中设置
路径
(状态)和
转换器参数
(样式名称)使其工作。我将更新我的问题以显示结果,再次感谢!
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        var status = value.ToString();
        var styleName = parameter.ToString();

        _resourceDictionary.Source = new System.Uri(string.Format("pack://application:,,,/Resources/ScreenI2Style{0}.xaml", status));

        return _resourceDictionary[styleName];
    }
<Style x:Key="TextBlockCowName" TargetType="TextBlock">
    <Setter Property="Foreground" Value="{StaticResource SomeBrush}" />
</Style>
<UserControl x:Class="WpfModifyDifferentView.Views.CowInfoView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
             xmlns:local="clr-namespace:WpfModifyDifferentView"
             Style="{Binding Path=Status, Converter={StaticResource myConverter}}">
        <UserControl.Resources>
            <local:MyConverter x:Key="myConverter" />
        </UserControl.Resources>
public class MyConverter : IValueConverter {
        private ResourceDictionary dictionary;

        public MyConverter() {
            if (dictionary == null) {
                dictionary = new ResourceDictionary();
                dictionary.Source = new Uri("pack://application:,,,/WpfModifyDifferentView;Component/Resources/Styles.xaml");
            }
        }
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
            switch (value.ToString()) {
                case "ok":
                    return dictionary["myKeyForOkStyle"] as Style;
                case "hungry":
                    return dictionary["myKeyForHungryStyle"] as Style;
                case "dead":
                    return dictionary["myKeyForDeadStyle"] as Style;
                default:
                    return null;
            }
        }

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