资源文件内的属性能否直接通过绑定应用到控件?答案是肯定的。
比如,我们要直接把下面的<SolidColorBrush x:Key="RedBrush" Color="#FFFF0000" />直接绑定到一个TextBlock的Foreground属性。
<Application x:Class="StaticResourcesWithBinding.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="Window1.xaml">
<Application.Resources>
<SolidColorBrush x:Key="RedBrush" Color="#FFFF0000" />
</Application.Resources>
</Application>
办法是直接把资源文件内的Key的名字绑定到控件,
public class MyViewModel
{
public string MyResourceKey { get; private set; }
public MyViewModel(string myResourceKey)
{
MyResourceKey = myResourceKey;
}
}
直接绑定可以吗?
<Window x:Class="StaticResourcesWithBinding.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Width="400" Height="200">
<Grid>
<TextBlock Text="Hello World" FontSize="48" Foreground="{StaticResource {Binding MyResourceKey}}" />
</Grid>
</Window>
但这样是行不通的。
必须要用下面的类进行转换
using System;
using System.Windows;
using System.Windows.Data;
using System.Windows.Markup;
namespace StaticResourcesWithBinding
{
public class BindableStaticResource : StaticResourceExtension
{
private static readonly DependencyProperty DummyProperty;
static BindableStaticResource()
{
DummyProperty = DependencyProperty.RegisterAttached("Dummy",
typeof(Object),
typeof(DependencyObject),
new UIPropertyMetadata(null));
}
public Binding MyBinding { get; set; }
public BindableStaticResource()
{
}
public BindableStaticResource(Binding binding)
{
MyBinding = binding;
}
public override object ProvideValue(IServiceProvider serviceProvider)
{
var target = (IProvideValueTarget)serviceProvider.GetService(typeof(IProvideValueTarget));
var targetObject = (FrameworkElement)target.TargetObject;
MyBinding.Source = targetObject.DataContext;
var DummyDO = new DependencyObject();
BindingOperations.SetBinding(DummyDO, DummyProperty, MyBinding);
ResourceKey = DummyDO.GetValue(DummyProperty);
return ResourceKey != null ? base.ProvideValue(serviceProvider) : null;
}
public new object ResourceKey
{
get
{
return base.ResourceKey;
}
set
{
if (value != null)
{
base.ResourceKey = value;
}
}
}
}
}
然后,我们就可以通过以下方式绑定了:
<Window x:Class="StaticResourcesWithBinding.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:StaticResourcesWithBinding="clr-namespace:StaticResourcesWithBinding"
Title="Window1" Width="400" Height="200">
<Grid>
<TextBlock Text="Hello World" FontSize="48" Foreground="{StaticResourcesWithBinding:BindableStaticResource {Binding MyResourceKey}}" />
</Grid>
</Window>
后面的代码:
public partial class Window1
{
public Window1()
{
this.DataContext = new MyViewModel("RedBrush");
InitializeComponent();
}
}
本文完整源码下载