Wpf 声明资源的确切效果是什么?

Wpf 声明资源的确切效果是什么?,wpf,xaml,Wpf,Xaml,使用XAML创建样式时: <Style x:Key="tbxWithValidation" TargetType="TextBox"> <Style.Setters> <Setter Property="Validation.ErrorTemplate" Value="{StaticResource errorTemplate}"/> ... </Style.Setters> </Style&g

使用XAML创建样式时:

<Style x:Key="tbxWithValidation" TargetType="TextBox">
    <Style.Setters>
        <Setter Property="Validation.ErrorTemplate" Value="{StaticResource errorTemplate}"/>
        ...
    </Style.Setters>
</Style>
你能帮我澄清一下吗(我正在学习WPF)

通过设计,对象的每个实例在对象图中只允许存在一次。”重用”或共享(
x:Shared=“True”
)指示XAML解析器在内部创建共享实例的副本,以便XAML解析器可以将它们插入元素树中的各个位置。但由于这是副本,它们实际上引用的是同一个共享实例

扩展
UIElement
的所有对象都有例外。这些对象的实例在对象图中只能存在一次:这就是为什么
System.Windows.Controls.Image
等元素在图形中的多个位置使用时会神奇地消失,例如单个图标与多个
按钮
元素一起使用时。在这种情况下,一次只能看到一个图标

无法共享
UIElement
的实例(由多个资源实例引用)-它们是唯一的。这意味着作者必须明确创建所需数量的实例。
这就是为什么在C#(代码隐藏)中创建
按钮
实例,然后将其添加到两个不同的
网格
元素时,会引发以下异常:

指定的元素已经是另一个元素的逻辑子元素

因此,这意味着像
样式
这样的共享资源只有在声明在多个资源中引用的
UIElement
对象(比如
Image
)时才是关键的:

<Style x:Key="SaveButton" TargetType="ButtonBase">
    <Setter Property="Content">
        <Setter.Value>
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="Save"/>                
                <Image Source="Resources\icons\save.png" />
            </StackPanel>
        </Setter.Value>
    </Setter>
</Style>
现在,XAML解析器必须为每个引用创建
样式的新实例

某种程度上类似的东西也适用于
ControlTemplate
。默认情况下也会共享,但不会共享其内容。
对于对
控制模板的每次引用,都会创建内容元素的新实例。
因此,将
按钮
的内容声明为
控制模板
内容模板
(而不是像上面那样直接通过
样式设置
按钮。内容
),也可以解决上述问题


并不意味着资源是静态的。它是一个标记扩展,指示XAML解析器查找资源树以查找预定义实例。同样的道理。唯一的区别是
StaticResource
指示XAML解析器在编译时解析对资源的引用,而
DynamicResource
让XAML解析器创建一个表达式,该表达式将在运行时进行计算(延迟)
DynamicSource
因此在运行时解析资源。

该样式不会针对每次使用都进行复制,而是为依赖项属性设置默认值。模板的工作原理与其他用于制作衣服或果冻模具的模板类似。模板显示每次生成这些控件的实例。它们不是相同的控件。如果您将一个可视对象定义为一个资源,那么这是一件独特的事情,如果您在同一个视图中尝试使用它两次,就会发生不好的事情。@Andy,-不祥。而且也是错误的:@Ash,如果您将视觉定义为资源。一个视觉对象只能有一个父对象,因此最好的情况是您只能看到视觉对象一次。我认为这很糟糕。这是一个我们希望经常看到的答案,谢谢。事实上,这个话题没有我最初想象的那么简单。
<Style x:Key="TbxWithValidation" TargetType="TextBox">
    <Style.Setters>
        <Setter Property="Validation.ErrorTemplate" Value="{StaticResource ErrorTemplate}"/>
        ...
    </Style.Setters>
</Style>
<Style x:Shared="False" x:Key="TbxWithValidation" TargetType="TextBox">
  ...
</Style>
<Style x:Key="SaveButton" TargetType="ButtonBase">
    <Setter Property="Content">
        <Setter.Value>
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="Save"/>                
                <Image Source="Resources\icons\save.png" />
            </StackPanel>
        </Setter.Value>
    </Setter>
</Style>
<Style x:Shared="False" x:Key="SaveButton" TargetType="ButtonBase">
    <Setter Property="Content">
        <Setter.Value>
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="Save"/>
                <Image Source="Resources\icons\save.png" />
            </StackPanel>
        </Setter.Value>
    </Setter>
</Style>