Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/css/36.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
在UWP应用程序中重写Generic.xaml中的资源_Xaml_Custom Controls_Uwp - Fatal编程技术网

在UWP应用程序中重写Generic.xaml中的资源

在UWP应用程序中重写Generic.xaml中的资源,xaml,custom-controls,uwp,Xaml,Custom Controls,Uwp,这是我的Generic.xaml,我在其中为我的控件(CustomControlBackground)定义默认背景色: 在App.xaml中,我要覆盖Generic.xaml中的默认背景: <Application x:Class="TomShane.Framework.Demo.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schem

这是我的Generic.xaml,我在其中为我的控件(CustomControlBackground)定义默认背景色:


在App.xaml中,我要覆盖Generic.xaml中的默认背景:

<Application
    x:Class="TomShane.Framework.Demo.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:TomShane.Framework.Demo"
    xmlns:ctrl="using:TomShane.Framework.Controls"
    RequestedTheme="Dark">
  <Application.Resources>
    <ResourceDictionary>
      <ResourceDictionary.ThemeDictionaries>
        <ResourceDictionary x:Key="Default">
          <SolidColorBrush x:Key="CustomControlBackground" Color="Red"/>
        </ResourceDictionary>
      </ResourceDictionary.ThemeDictionaries>
    </ResourceDictionary>
  </Application.Resources>
</Application>
<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:themes="using:CustomControlLibrary.Themes">

    <ResourceDictionary.MergedDictionaries>
        <themes:CustomControlTheme />
    </ResourceDictionary.MergedDictionaries>

</ResourceDictionary>

使用此技术,我可以覆盖UWP系统资源(如SystemControlBackgroundBaseLowBrush),但当我尝试覆盖CustomControlBackground时,控件的背景始终保持灰色

我遗漏了什么?

逻辑是错误的

我们只能在较低范围的ResourceDictionary中重写较高范围的ResourceDictionary。实际上,这与资源查找行为有关,而与首先加载哪个xaml文件无关

在WinRT xaml应用程序中,资源字典范围如下所示(不是MS官方图片):

基于以上,我们可以在app.xaml中覆盖系统默认资源,在page.xaml中覆盖系统/应用程序资源,等等

因此,在代码中,实际上,generic.xaml中定义的资源将覆盖app.xaml中定义的资源。如果我们只是从generic.xaml中删除资源
CustomControlBackground
,您将得到红色背景

[更新]

如果您确实希望有一个默认主题,可以保留设计,但我们不能对resourcedictionary使用x:default

例如,如果请求的主题是深色的(在您的案例中)。您只需使用以下命令即可覆盖app.xaml中的默认值

        <ResourceDictionary.ThemeDictionaries>
            <ResourceDictionary x:Key="Dark">
                <SolidColorBrush x:Key="CustomControlBackground" Color="Yellow"/>
            </ResourceDictionary>
        </ResourceDictionary.ThemeDictionaries>


或者,您只能将主题放入单独的文件中,并仅在客户端应用程序的app.xaml中引用它。但是您必须重写文件以使用不同的值

不幸的是,没有一种很好的方法来定义自定义控件的主题资源,使它们可以像SystemControlBackgroundBaseLowBrush这样的内置资源一样被覆盖。但如果您愿意在运行时移动对象,则有一个解决方法。诀窍是最终出现这样一种情况:默认资源不包含在Generic.xaml中,而是在与应用程序的资源合并的资源字典中定义,可以在其中重写它们。实现这一点的方法不止一种

一种方法是创建一个单独的资源字典,其中包含一个带有关联代码文件的x:Class。在其中定义默认的主题资源。然后找出一种在运行时将类的实例合并到应用程序资源中的方法。一种方法是在控件的静态构造函数中。注意不要合并多个实例

我更喜欢的另一种方法是使用资源字典的代码隐藏,在其中定义控件的默认样式。但是不能为Generic.xaml保留代码,因为框架永远不会实例化类的实例。相反,将样式移动到它自己的资源字典中(后面有x:Class和code),并将新字典的实例添加到Generic.xaml的合并字典中。在调用InitializeComponent之后,您将能够在此资源字典的构造函数中移动内容。例如,如果在xaml文件中,您在MergedDictionaries集合中定义了一个资源字典,并将主题资源放在其中,那么在运行时,您将能够从MergedDictionaries集合中删除该字典,并将其合并到应用程序的资源中

这两种方法的一个限制是,如果您想按主题覆盖资源,即亮和暗。将覆盖资源直接放置到App.xaml的资源中会起作用,但不允许不同主题使用不同的值。为了实现这一点,有必要在资源字典的主题资源中定义覆盖资源,该资源字典本身位于应用程序资源的合并字典中。(我不知道,但似乎这可能是一个bug。)

CustomControl.xaml:

<ResourceDictionary x:Class="CustomControlLibrary.Themes.CustomControlTheme" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:CustomControlLibrary">

    <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary>
            <ResourceDictionary.ThemeDictionaries>
                <ResourceDictionary x:Key="Light">
                    <SolidColorBrush x:Key="CustomControlBackground" Color="#000000" />
                </ResourceDictionary>
                <ResourceDictionary x:Key="Dark">
                    <SolidColorBrush x:Key="CustomControlBackground" Color="#FFFFFF" />
                </ResourceDictionary>
            </ResourceDictionary.ThemeDictionaries>
        </ResourceDictionary>
    </ResourceDictionary.MergedDictionaries>

    <Style TargetType="local:CustomControl">
        <Setter Property="Background" Value="{ThemeResource CustomControlBackground}" />
    </Style>    

</ResourceDictionary>
Generic.xaml:

<Application
    x:Class="TomShane.Framework.Demo.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:TomShane.Framework.Demo"
    xmlns:ctrl="using:TomShane.Framework.Controls"
    RequestedTheme="Dark">
  <Application.Resources>
    <ResourceDictionary>
      <ResourceDictionary.ThemeDictionaries>
        <ResourceDictionary x:Key="Default">
          <SolidColorBrush x:Key="CustomControlBackground" Color="Red"/>
        </ResourceDictionary>
      </ResourceDictionary.ThemeDictionaries>
    </ResourceDictionary>
  </Application.Resources>
</Application>
<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:themes="using:CustomControlLibrary.Themes">

    <ResourceDictionary.MergedDictionaries>
        <themes:CustomControlTheme />
    </ResourceDictionary.MergedDictionaries>

</ResourceDictionary>


您首先加载哪一个?为什么要覆盖App.xaml中的颜色,为什么不首先在那里定义它呢?Generic.xaml是与主应用程序分离的主题/控件程序集的一部分。它应该是通用的,主应用程序应该能够覆盖一些基本颜色,如重音等。我没有显式加载Generic.xaml,它是自动加载的,所以我只需要在App.xaml中重新定义资源。没错,但是我需要在主题程序集中的某个地方为CustomControlBackground定义默认背景,然后在App.xaml中重写它。由于Generic.xaml是自动加载的,所以我无法控制加载内容、加载时间以及加载顺序。我(几乎)确信在旧的WPF应用程序中,我的OP中的步骤实际上是有效的。我不认为WPF应用程序会做你想做的事情。实际上,它与资源查找行为有关。主题文件夹中的generic.xaml始终是查找此场景的第一个位置。一旦找到资源,查找就会停止。我承认,WPF肯定有错。无论如何,有没有一种方法可以在UWP应用程序中实现这一点?要使用使用特定资源并能够在客户端应用程序(app.xaml)中重写自定义控件的独立程序集,请执行以下操作:?如果不是在XAML中,那么是在代码隐藏中?感谢您的更新,不幸的是它仍然无法工作。我已将所有“默认”词典更改为“深色”,但颜色仍然没有被覆盖,并保持为灰色。如果它对你有用的话,如果我能看到你的示例代码就太好了。我很高兴这在UWP中不是真的。