[英]How to using DynamicResourceExtension and IValueConverter for set color at run-time?
我有一個枚舉:
public enum SignalColor
{
None,
Signal01A,
Signal02A
}
和LightTheme.xaml:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="../Colors.xaml"/>
</ResourceDictionary.MergedDictionaries>
<!--Signal colors-->
<SolidColorBrush x:Key="Signal01ABrush" Color="#8bc34a"/>
<SolidColorBrush x:Key="Signal01BBrush" Color="#5b9914"/>
</ResourceDictionary>
我有SignalColorSelector控件來選擇顏色
<c:SignalColorSelector Name="Test" Grid.Column="0" AllowsTransparent="True" SelectedColor="Signal02A"></c:SignalColorSelector>
<c:SignalColorSelector Name="ChooseColor" Grid.Column="1" Header="Choose a color" SelectedColor="Signal01A"></c:SignalColorSelector>
如何創建從MarkupExtension派生並實現IValueConverter的SignalColorToBrushConverter類? 在Convert方法中,該值應為SignalColor類型。 如果它是SignalColor.None,則返回DependencyProperty.UnsetValue。 否則,使用DynamicResourceExtension返回相應的信號顏色筆刷 。
編輯1我創建了SignalColorToBrushConverter類:
public class SignalColorToBrushConverter : MarkupExtension, IValueConverter
{
private static DynamicResourceExtension dynamicResource = new DynamicResourceExtension();
public SignalColorToBrushConverter()
{
}
public override object ProvideValue(IServiceProvider serviceProvider)
{
return this;
}
public object Convert(object value, Type tagertType, object parameter, System.Globalization.CultureInfo culture)
{
if (value == null)
return null;
SignalColor signalColor = (SignalColor)Enum.Parse(typeof(SignalColor), value.ToString());
switch (signalColor)
{
case SignalColor.None:
return DependencyProperty.UnsetValue;
case SignalColor.Signal01A:
dynamicResource.ResourceKey = "Signal01ABrush";
break;
case SignalColor.Signal01B:
dynamicResource.ResourceKey = "Signal01BBrush";
break;
case SignalColor.Signal02A:
dynamicResource.ResourceKey = "Signal02ABrush";
break;
case SignalColor.Signal02B:
dynamicResource.ResourceKey = "Signal02BBrush";
break;
}
try
{
return Application.Current.FindResource(dynamicResource.ResourceKey);
}
catch (ResourceReferenceKeyNotFoundException)
{
return DependencyProperty.UnsetValue;
}
}
然后,使用它:
<TextBlock Text="Choose a color" Width="100" FontWeight="Bold" HorizontalAlignment="Left"
Foreground="{Binding Path=SelectedColor, Converter={v:SignalColorToBrushConverter}, ElementName=ChooseColor}"/>
您可以創建如下所示的擴展標記
public class SignalColorExtension : MarkupExtension
{
public SignalColor IncomingSignalColor
{
get;
set;
}
public SignalColorExtension() { }
public SignalColorExtension(string color)
{
SignalColor outColor;
if (! SignalColor.TryParse(color,true,out outColor))
IncomingSignalColor = SignalColor.None;
}
public override object ProvideValue(IServiceProvider serviceProvider)
{
var target = serviceProvider.GetService(typeof(IProvideValueTarget)) as IProvideValueTarget;
var host = target.TargetObject as FrameworkElement;
if (host != null && IncomingSignalColor != SignalColor.None)
{
var colorResourse = host.TryFindResource(IncomingSignalColor.ToString());
return colorResourse;
}
return DependencyProperty.UnsetValue;
}
}
並使用TargetObject上的find Resource查找顏色(如果它們與dynamicresource標記一樣存在)。 然后,您可以像下面那樣使用標記:
<Grid Background="{sigColor:SignalColor Signal01A}" >
其中sigColor是標記擴展所在的程序集的命名空間。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.