wpf 使用 IValueConverter 进行动态样式绑定
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12060761/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Dynamic Style Binding with IValueConverter
提问by Mike Perrenoud
I am trying to set a style, which is defined in the App.xaml, dynamically when loading a user control and it's just not applying the style for some reason (i.e. there is no error occurring, it's just not applying the style).
我试图App.xaml在加载用户控件时动态地设置一个在.
I'm sure it's because I've defined the binding wrong, but I'm unable to figure out what I need to do differently to get it to work.
我确定这是因为我定义了错误的绑定,但我无法弄清楚我需要做些什么才能让它工作。
App.xaml Style
App.xaml 样式
The style I'm after is the RunningTitleBlockand it's comprised of a couple other styles that I've included in the below code sample.
我所追求的风格是RunningTitleBlock,它由我在下面的代码示例中包含的其他几种风格组成。
<Style TargetType="Label">
<Setter Property="Margin" Value="4"/>
</Style>
<Style TargetType="Label"
BasedOn="{StaticResource {x:Type Label}}"
x:Key="HeaderBlock">
<Setter Property="FontSize" Value="16"/>
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="Foreground" Value="White"/>
</Style>
<Style TargetType="Label"
BasedOn="{StaticResource ResourceKey=HeaderBlock}"
x:Key="TitleBlock">
<Setter Property="Foreground" Value="Black"/>
</Style>
<Style TargetType="Label"
BasedOn="{StaticResource ResourceKey=TitleBlock}"
x:Key="RunningTitleBlock">
<Setter Property="Background">
<Setter.Value>
<LinearGradientBrush StartPoint="0.0, 0.5"
EndPoint="1.0, 0.5">
<GradientStop Color="White" Offset="0.0"/>
<GradientStop Color="Green" Offset="1.0"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Style>
Binding on the user control
在用户控件上绑定
I'm trying to get the Bindingto bind to a value returned from a value converter.
我正在尝试将Binding要绑定到从值转换器返回的值。
Style="{DynamicResource ResourceKey={Binding Path=MonitoringType, Converter={StaticResource TSConverter}}}"
Code
代码
MonitoringTypes Enum
监控类型枚举
public enum MonitoringTypes
{
Running,
Failed,
Paused,
Favorites,
}
User Control
用户控制
Here what I'm trying to do is concatenate the string value of the MonitoringTypesenum value that's passed in with some well known text to build a style name that exists in the App.xaml. The value converter is being called andreturning the correct value, but for some reason the style isn't applying.
在这里,我想要做的是将MonitoringTypes传入的枚举值的字符串值与一些众所周知的文本连接起来,以构建一个存在于App.xaml. 正在调用值转换器并返回正确的值,但由于某种原因,该样式不适用。
/// <summary>
/// Interaction logic for MonitorWorkflow.xaml
/// </summary>
public partial class MonitorWorkflow : UserControl
{
public MonitorWorkflow(MonitoringTypes monitoringType)
{
InitializeComponent();
this.DataContext = new MonitorWorkflowViewModel { MonitoringType = monitoringType };
}
}
public class MonitorWorkflowViewModel
{
public MonitoringTypes MonitoringType { get; set; }
}
public class TitleStyleValueConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
var type = (MonitoringTypes)value;
return string.Format("{0}TitleBlock", Enum.GetName(typeof(MonitoringTypes), type));
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return Enum.Parse(typeof(MonitoringTypes), value.ToString().Substring(0, value.ToString().IndexOf("TitleBlock")));
}
}
回答by code4life
My suggestion would be to skip the DynamicResourcestatement and using the Converterprovide the Styledirectly.
我的建议是跳过该DynamicResource语句并直接使用Converter提供Style。
Style="{Binding Path=MonitoringType, Converter={StaticResource TSConverter}}"
In TSConverter, you can return a Stylerather than a string. Kind of like this:
在 中TSConverter,您可以返回一个Style而不是一个字符串。有点像这样:
public class TitleStyleValueConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter,
System.Globalization.CultureInfo culture)
{
var type = (MonitoringTypes)value;
var styleToReturn = FindResource(
string.Format("{0}TitleBlock",
Enum.GetName(typeof(MonitoringTypes), type)));
if (styleToReturn != null)
return (Style)styleToReturn;
else
return null;
}
public object ConvertBack(object value, Type targetType, object parameter,
System.Globalization.CultureInfo culture)
{
// not sure if you need this anymore...
return Enum.Parse(typeof(MonitoringTypes), value.ToString().Substring(0,
value.ToString().IndexOf("TitleBlock")));
}
}
This is what I did but with the following code instead. I actually just answered my own question while you answered it as well. Good timing!
这就是我所做的,但使用以下代码代替。我实际上只是回答了我自己的问题,而您也回答了。好时机!
public class TitleStyleValueConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
var type = (MonitoringTypes)value;
return App.Current.Resources[string.Format("{0}TitleBlock", Enum.GetName(typeof(MonitoringTypes), type))];
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return Enum.Parse(typeof(MonitoringTypes), value.ToString().Substring(0, value.ToString().IndexOf("TitleBlock")));
}
}
回答by patrick
public static Style DayModeButton = null;
void loadStyle()
{
Uri uri1 = new Uri("/Resources/ButtonStyle.xaml", UriKind.Relative);
ResourceDictionary resDict1 = Application.LoadComponent(uri1) as ResourceDictionary;
foreach (object obj in resDict1.Values) //Set explicit reference
if (obj is Style) DayModeButton = (Style)obj;
}
[ValueConversion(typeof(object), typeof(Style))]
public class GetStyleConverter: IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return DayModeButton ;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return 0;
}
}

