绑定到 ResourceDictionary 中的属性

Posted

技术标签:

【中文标题】绑定到 ResourceDictionary 中的属性【英文标题】:Bind to a property in a ResourceDictionary 【发布时间】:2021-12-13 20:20:16 【问题描述】:

我的项目中有一个Templates.xaml 文件,其中包含样式的ResourceDictionary

我想将DropShadowEffectDirection 绑定到MyNamespace.MyPage.LightDirection。目前我是这样做的:

// MyPage.xaml.cs
/// <summary>
/// Direction of light source for shadows and gradients.
/// </summary>
public static double LightDirection => 45;
<!--Templates.xaml-->
<Style x:Key="ControlButtons" TargetType="x:Type Button">
    <Setter Property="Effect">
        <Setter.Value>
            <DropShadowEffect ShadowDepth="4" Direction="Binding LightDirection" Color="Black" Opacity="0.5" BlurRadius="4" />
        </Setter.Value>
    </Setter>
    <!--Other Setters-->
</Style>
<!--MyPage.xaml-->
<Page x:Name="MyPage"
      DataContext="Binding ElementName=MyPage">
      <!--MyPage as some other default attributes which I didn't write here-->
    <Grid>
        <Button x:Name="MyButton" Style="StaticResource ControlButtons">
            My Button
        </Button>
    </Grid>
</Page>

它有效。阴影方向设置为LightDirection,程序正常运行。但是,在调试时,调试器显示绑定错误:

找不到目标元素的管理 FrameworkElement 或 FrameworkContentElement。

我的错误是什么?我应该如何防止这个错误?

【问题讨论】:

【参考方案1】:

我建议做一个常量

namespace MyNamespace

    public class Constants
    
        public static double LightDirection  get; set; 
    

XAML

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"                
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:local="clr-namespace:MyNamespace">
    <Style x:Key="ControlButtons" TargetType="x:Type Button">
        <Setter Property="Effect">
            <Setter.Value>
                <DropShadowEffect ShadowDepth="4"
                                  Direction="x:Static local:Constants.LightDirection"
                                  Color="Black"
                                  Opacity="0.5" 
                                  BlurRadius="4" />
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>

或者直接在XAML中声明常量

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"                
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:local="clr-namespace:MyNamespace"
                    xmlns:sys="clr-namespace:System;assembly=mscorlib" >
    <sys:Double x:Key="LightDirection">45.0</sys:Double>
    <Style x:Key="ControlButtons" TargetType="x:Type Button">
        <Setter Property="Effect">
            <Setter.Value>
                <DropShadowEffect ShadowDepth="4"
                                  Direction="StaticResource LightDirection"
                                  Color="Black"
                                  Opacity="0.5" 
                                  BlurRadius="4" />
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>

【讨论】:

它可以工作并且错误消失了。但是我在 C# 代码的某些部分也使用了LightDirection 你在哪里导入你的字典? 我使用 Blend 来添加这本词典。它将&lt;ResourceDictionary Source="Templates.xaml" /&gt; 添加到App.xaml 也就是说,您可以从 C# 代码中访问字典键:var lightDirection = Application.Current.Resources["LightDirection"] 如果你使用 MVVM 但是上面的方法并不好。如果您想要更简洁的代码,您可以在 C# 和 XAML 中复制这些数据

以上是关于绑定到 ResourceDictionary 中的属性的主要内容,如果未能解决你的问题,请参考以下文章

将属性绑定到ResourceDictionary上定义的样式以消除代码重复

如何在XAML中直接用IValueConverter绑定ResourceDictionary的值?

将 ResourceDictionary 添加到类库

ResourceDictionary 中的 IValueConverter

合并ResourceDictionary

在 ResourceDictionary 中交换 DynamicResource