Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Wpf 覆盖XAML中的资源_Wpf_Xaml_User Controls_Resources_Overriding - Fatal编程技术网

Wpf 覆盖XAML中的资源

Wpf 覆盖XAML中的资源,wpf,xaml,user-controls,resources,overriding,Wpf,Xaml,User Controls,Resources,Overriding,我有以下UserControl: <UserControl x:Class="MyControl" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlforma

我有以下
UserControl

<UserControl x:Class="MyControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">

    <UserControl.Resources>
        <SolidColorBrush x:Key="ColorKey" Color="Orange"/>
    </UserControl.Resources>

    <Grid Background="{StaticResource ColorKey}">

    </Grid>
</UserControl>

我是这样用的:

<Window x:Class="MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:OverrideResource"
    Title="MainWindow" Height="350" Width="525">

    <Window.Resources>
        <SolidColorBrush x:Key="OtherColorKey" Color="Blue"/>
    </Window.Resources>

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <local:MyControl Grid.Row="0">
            <local:MyControl.Resources>
                <SolidColorBrush x:Key="ColorKey" Color="Red"/>
            </local:MyControl.Resources>
        </local:MyControl>

        <Grid Grid.Row="1">
            <Grid.Resources>
                <SolidColorBrush x:Key="OtherColorKey" Color="Green"/>
            </Grid.Resources>
            <Grid Background="{StaticResource OtherColorKey}"/>
        </Grid>
    </Grid>
</Window>

覆盖resource
OtherColorKey
的工作方式与我预期的一样;网格的背景为绿色
。但是我想覆盖
资源
,该资源在
用户控件
中使用(在我的示例中为
颜色键
)。但我有个例外:

项目已添加。字典中的键:正在添加的“ColorKey”键:“ColorKey”

这只是一个简化的例子,实际上我需要它来完成更复杂的任务。我知道,对于examle,DevExpress使用类似的机制来定制控件(但它们不是使用字符串作为键,而是使用从
ResourceKey
派生的对象)。但我无法找到一个简单的工作示例来单独实现这样的事情


感谢您的帮助。

正在将OtherColorKey添加到两个不同的词典(窗口和网格)。正在将ColorKey添加到同一词典(MyControl)

更好的方法是在MyControl中声明Brush类型的DependencyProperty,并将其设置为:

   <local:MyControl Grid.Row="0" MyBrush="Red" />

在MyControl中,只需将任何需要的内容绑定到MyBrush属性

<UserControl x:Class="MyControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300" x:Name=Me>

    <Grid Background="{Binding MyBrush, ElementName=Me}">

    </Grid>
</UserControl>

阅读您的帖子并回复第一个答案后,您似乎正在编写一个需要跟踪多个样式元素的应用程序。让它们组织起来并易于维护的最好方法是使用ResourceDictionary并引用它

对我来说,我有一个更容易的时间,当我分开我的基于他们定义的,一个用于画笔和颜色,一个用于控制模板和样式(如果项目非常复杂,那么它取决于其他几个因素-这只是一个相对简单的项目)

一旦定义了这些ResourceDictionary文件,您就可以在App.xaml文件中引用它们,这样就可以在整个应用程序中应用它们,而无需始终在页面的实际xaml中重新定义笔刷或模板

下面是App.xaml的外观示例:

<Application
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    x:Class="MyColorBlock.App"
    StartupUri="MainWindow.xaml">
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="Resources/BrushesAndColors.xaml"/>
                <ResourceDictionary Source="Resources/StylesAndTemplates.xaml"/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
</Application>

如前所述,这是一个非常简化的示例,因此源文件位于App.xaml所在的同一个项目中—就在Resources文件夹中。由于定义的样式和模板取决于您定义的颜色,因此BrushesAndColors.xaml在StylesAndTemplates.xaml之前被引用

对于ResourceDictionary BrushesAndColor.xaml:

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:OverrideResource">

        <SolidColorBrush x:Key="BlueBrush" Color="Blue"/>
        <SolidColorBrush x:Key="RedBrush" Color="Red"/>
        <SolidColorBrush x:Key="GreenBrush" Color="Green"/>

</ResourceDictionary>

笔刷与您定义的相同,但是现在可以在整个应用程序中通过其键引用它们

对于StylesAndTemplates.xaml:

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:OverrideResource">

    <!-- Adding the MergedDictionaries in this ResourceDictionary allows the control templates and styles to reference the colors and brushes defined in BrushesAndColors.xaml. Note: It is a relative link, both files in this example in the same folder "Resources"  -->
    <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="BrushesAndColors.xaml"/>
    </ResourceDictionary.MergedDictionaries>

    <Style x:key="MyControlStyle" TargetType="{x:Type local:MyControl}">
        <Setter Property="HorizontalAlignment" Value="Stretch"/>
        <Setter Property="VerticalAlignment" Value="Stretch"/>
        <Setter Property="Background" Value="{StaticResource RedBrush}"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type local:MyControl}">
                <!-- by giving the border background the value of {TemplateBinding Background} it is now set based on what the style's property has been defined as -->
                    <Border Background="{TemplateBinding Background}">
                        <TextBlock Text="Red Block Text"/>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>


    <!-- since the style is based on a predefined one it inherits that particular style's definition.
        However, the background color of this stylehas been redefined, and will use that background color
        on any control it is applied to instead-->

    <Style x:Key="MyControlStyleTwo" TargetType="{x:Type local:MyControl}" BasedOn="{StaticResource MyControlStyle}">
        <Setter Property="Background" Value="{StaticResource BlueBrush}"/>
    </Style>


</ResourceDictionary>

出于习惯,我仍然引用ResourceDictionary,这本词典需要确保定义的样式和模板能够在创建它们时找到我引用的资源

第二种风格,我基于第一种风格,所以我不必重写整个风格,但我可以简单地改变背景的颜色。因此,它将看起来像第一个,除了不同的背景色

对于主窗口-将稍微更改:

<Window x:Class="MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:OverrideResource"
    Title="MainWindow" Height="350" Width="525">

    <Grid Background="{StaticResource BlueBrush}">
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

      <local:MyControl Style="{StaticResource MyControlStyle}" Grid.Row="0" />
        <local:MyControl Style="{StaticResource MyControlStyleTwo}" Grid.Row="1"/>

    </Grid>
</Window>

您不再需要重新定义与应用程序UI相关的任何信息,从而使XAML更干净、更易于阅读

这可能不是一个“简单的解决方案”——但它肯定会让事情变得更容易。如果不止一个人参与该项目,它也将帮助其他任何人。通过在一个集中的区域中定义所有内容,您可以保持样式和颜色的一致性,并且没有人需要筛选不同的页面以找到使用的样式,他们只需参考适当的样式即可

这还允许控件只写入一次,但通过为其提供不同的样式/模板,您可以更改信息的显示方式—有助于将数据和显示信息分开:)


希望这能有所帮助,抱歉发了这么长的帖子,但这是我唯一能想到的解释我认为你如何才能最好地解决你的问题(并让它得到解决)的方法。

谢谢,我知道我可以添加新的依赖属性并以这种方式解决它。但正如我所写的,我发布的只是一个简单的例子。想象一下,不仅有单个笔刷作为资源,还有多个控制模板、样式或其他资源。我不想为每个要“覆盖”的资源添加依赖项属性。