如何从绑定值设置 Static/Dynamic 资源?

How can I set a Static/Dynamic resource from a binding value?

我想使用包含 TextBlock 控件的数据模板添加动态项目,但 TextBlock 控件的文本将从 XAML ResourceDictionary 中选择。静态资源名称将根据绑定值的结果得到。

我该怎么做? 我正在尝试这样的事情,但不起作用。

 <DataTemplate x:Key="languageItemTemplate">
            <ContentControl>
                <StackPanel>                    
                     <TextBlock Text="{StaticResource  {Binding ResourceName}}"></TextBlock>    
                     <TextBlock Text="{DynamicResource  {Binding ResourceName}}"></TextBlock>                    
                </StackPanel>
            </ContentControl>
 </DataTemplate>

更新 感谢 Tobias,他的答案的第一个选项有效。但我需要首先实例化转换器才能使其工作。哪一个是最好的主意?

在application_startup方法中并将其用于所有应用程序或在window的Window.Resources中我使用转换器?

也许可以将两者合并并在 Application.Resources 上进行?

感谢您的回答。

        private void Application_Startup(object sender, StartupEventArgs e)
        {
            LoadConverters();
        }
        private void LoadConverters()
        {
            foreach (var t in System.Reflection.Assembly.GetExecutingAssembly().GetTypes())
            {
                if (t.GetInterfaces().Any(i => i.Name == "IValueConverter"))
                {
                    Resources.Add(t.Name, Activator.CreateInstance(t));
                }
            }
        }

<local:BindingResourceConverter x:Key="ResourceConverter"/>
<DataTemplate x:Key="languageItemTemplate">
            <ContentControl>
                <StackPanel>                    
                     <TextBlock Text="{Binding Name, Converter={StaticResource ResourceConverter }}" />                 
                </StackPanel>
            </ContentControl>
 </DataTemplate>

如果资源是应用程序级资源,您可以简单地使用转换器将资源名称转换为实际对象,如下所示:

public class BindingResourceConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        string resourceKey = value as string;
        if (!String.IsNullOrEmpty(resourceKey))
        {
            var resource = Application.Current.FindResource(resourceKey);             
            if (resource != null)
            {
                return resource;
            }
        }
        return Binding.DoNothing;
    }

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

并像这样使用它:

<TextBlock Text="{Binding ResourceKey, Converter={StaticResource ResourceConverter}}" />

如果资源在局部范围,我们需要对控件的引用来搜索它的资源。您可以使用附加的 属性:

获取资源名称和控件
public class TextBlockHelper
{
    public static readonly DependencyProperty TextResourceKeyProperty =
        DependencyProperty.RegisterAttached("TextResourceKey", typeof(string),
            typeof(TextBlockHelper), new PropertyMetadata(String.Empty, OnTextResourceKeyChanged));

    public static string GetTextResourceKey(DependencyObject obj)
    {
        return (string)obj.GetValue(TextResourceKeyProperty);
    }

    public static void SetTextResourceKey(DependencyObject obj, string value)
    {
        obj.SetValue(TextResourceKeyProperty, value);
    }

    private static void OnTextResourceKeyChanged(
        DependencyObject d,
        DependencyPropertyChangedEventArgs e)
    {
        string resourceKey = e.NewValue as string;
        if(d is TextBlock tb)
        {
            var r = tb.TryFindResource(resourceKey);
            if (r != null)
            {
                tb.Text = r.ToString();
            }
        }
    }
}

你可以这样使用它:

<Grid>
    <Grid.Resources>
        <sys:String x:Key="SomeLocalResource">LocalResource</sys:String>
    </Grid.Resources>
    <TextBlock h:TextBlockHelper.TextResourceKey="{Binding ResourceKey}" />
</Grid>