Mahapps,不适用于用户控件的主题

Mahapps, themes not applying to user controls

我有一个使用默认颜色加载的 MetroWindow。我有一个选项供用户更改样式。在 window 中,我使用内容控件在初始化此 window 时从代码后面动态设置用户控件(此 window 是从另一个应用程序初始化的,因此没有 app.xaml我使用 window 本身的资源)。 windows 的主要代码如下。在用户控件中,我使用了一些标签和一个选项卡控件。在 window 上,我有一个选项让用户能够更改从可用主题中选择的主题(如在您的演示项目中)。在所有标签中,我都使用动态资源。

当 window 首次加载时,将应用默认颜色并且所有内部控件也具有相同的主题。当我从 window 顶部更改主题时,window 边框、标题、发光发生变化,但内部控件保持旧主题(如选项卡控件 headers 等)我已经尝试了一切但这似乎并没有改变。

下面是我的代码:

    <Controls:MetroWindow x:Class="Test.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:Controls="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"
            Title="MainWindow" Height="300" Width="300" ShowMaxRestoreButton="False" ShowMinButton="False" 
            BorderBrush="{DynamicResource HighlightBrush}"
            GlowBrush="{DynamicResource HighlightBrush}" WindowStartupLocation="CenterScreen" 
            ResizeMode="NoResize" WindowTransitionsEnabled="False" TitleCaps="True"
            BorderThickness="1">
    <Window.Resources>
  <ResourceDictionary>
    <ResourceDictionary.MergedDictionaries>
      <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Controls.xaml" />
      <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Fonts.xaml" />
      <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Colors.xaml" />
      <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/Blue.xaml" />
      <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/BaseLight.xaml" />
      <ResourceDictionary Source="/Test;component/Resources/Icons.xaml" />
    </ResourceDictionary.MergedDictionaries>
  </ResourceDictionary>
</Window.Resources>

        <Border Margin="5" BorderBrush="Transparent" BorderThickness="0">
            <ContentControl x:Name="ChildContentControl"
                        HorizontalAlignment="Stretch" 
                        VerticalAlignment="Stretch">
            </ContentControl>
        </Border>
    </Controls:MetroWindow>

我的 window 背后的代码:

public partial class MainWindow : MetroWindow
{

    public MainWindow()
    {
        InitializeComponent();
        this.Initialize();
    }

    public MainWindow(string title, UserControl childControl)
    {
        try
        {
            InitializeComponent();
            this.Title = title;
            this.ChildContentControl.Content = childControl;
        }
        catch (Exception de)
        {
            throw de;
        }
    }
}

我的用户控件XAML

<UserControl x:Class="Test.UCDemo"
             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"
             xmlns:sys="clr-namespace:System;assembly=mscorlib"
             xmlns:local="clr-namespace:Test"
             xmlns:Controls="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"
             mc:Ignorable="d"
             d:DesignHeight="300" d:DesignWidth="300">
  <UserControl.Resources>
    <ResourceDictionary>
      <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="/Test;component/Resources/Icons.xaml" />
      </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>


  </UserControl.Resources>
  <Border>
    <Grid>
      <Grid.RowDefinitions>
        <RowDefinition Height="*"/>
      </Grid.RowDefinitions>
      <DockPanel Grid.Row="0" LastChildFill="True">

        <Grid Height="60" DockPanel.Dock="Bottom">

          <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="auto"/>
            <ColumnDefinition Width="5"/>
          </Grid.ColumnDefinitions>

          <Button Grid.Column="1"  Margin="5,0,5,0" Width="50" Height="50"
              Style="{DynamicResource MetroCircleButtonStyle}" Command="{Binding OKCommand}">
            <Rectangle Width="20"
               Height="20"
               Fill="{Binding Path=Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}">
              <Rectangle.OpacityMask>
                <VisualBrush Stretch="Fill"
                     Visual="{StaticResource appbar_check}" />
              </Rectangle.OpacityMask>
            </Rectangle>
          </Button>
        </Grid>
        <Grid DockPanel.Dock="Top" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="Transparent"
                  SnapsToDevicePixels="True"
                  ScrollViewer.HorizontalScrollBarVisibility="Hidden" ScrollViewer.VerticalScrollBarVisibility="Hidden">

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

          <Grid Grid.Row="0">
            <Grid.Resources>
              <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Controls.AnimatedSingleRowTabControl.xaml" />
            </Grid.Resources>
            <TabControl Margin="0,10,0,0" TabStripPlacement="Left"  ItemsSource="{Binding Catalogs}" SelectedItem="{Binding SelectedCatalog}">
              <TabControl.ItemTemplate>
                <!-- this is the header template-->
                <DataTemplate>
                  <TextBlock Text="{Binding Path=CaptionCat}" Foreground="{DynamicResource HighlightBrush}" FontSize="14" Margin="0,0,0,10" />
                </DataTemplate>
              </TabControl.ItemTemplate>
              <TabControl.ContentTemplate>
                <DataTemplate>
                  <ItemsControl ItemsSource="{Binding DataContext.SelectedCatalog.Books,RelativeSource={RelativeSource AncestorType={x:Type TabControl}}}">
                    <ItemsControl.ItemsPanel>
                      <ItemsPanelTemplate>
                        <WrapPanel ScrollViewer.VerticalScrollBarVisibility="Disabled"/>
                      </ItemsPanelTemplate>
                    </ItemsControl.ItemsPanel>
                    <ItemsControl.ItemTemplate>
                      <DataTemplate>
                        <Controls:Tile Height="125" Width="300" IsEnabled="{Binding IsEnabled}" Title="{Binding CaptionBook}"/>
                      </DataTemplate>
                    </ItemsControl.ItemTemplate>
                  </ItemsControl>
                </DataTemplate>
              </TabControl.ContentTemplate>
            </TabControl>
          </Grid>
        </Grid>

      </DockPanel>
    </Grid>
  </Border>


</UserControl>

我的用户控件后面的代码:

public partial class UCDemo : UserControl
{

    private VMDemo CatalogVM { set; get; }

    public UCDemo()
    {
        try
        {
            InitializeComponent();
            this.DataContext = new VMDemo();
        }
        catch (Exception de)
        {
            throw de;
        }
    }
}

最后是我如何从托管应用程序代码中调用 window 和嵌入式用户控件:

private void ShowDemoUI()
    {
        try
        {
            var child = new UILibrary.UCDemo();
            UILibrary.MainWindow window = new UILibrary.MainWindow("Book catalog", child);
            window.Height = 450;
            window.Width = 700;
            window.ShowDialog();
        }
        catch (Exception de)
        {
            throw de;
        }
    }

您需要移动 App.xaml

中的所有 ResourceDictionaries

之后,我认为您需要查看 Theme Manager

这是我所做的。在这个例子中,我所有的 Content Control 都有保存 Theme 即使我通过单击按钮更改主题:

public ShellView()
{
    this.InitializeComponent();
    var theme = ThemeManager.DetectAppStyle(Application.Current);
    ThemeManager.ChangeAppStyle(Application.Current, ThemeManager.GetAccent("Blue"), theme.Item1);
}

private void Button_Click(object sender, RoutedEventArgs e)
{
    var theme = ThemeManager.DetectAppStyle(Application.Current);
    ThemeManager.ChangeAppStyle(Application.Current, ThemeManager.GetAccent("Cyan"), theme.Item1);
}

代码需要在您的 Window 代码中(在我的例子中是 ShellView.cs),我假设它是 MainWindow.cs

这是另一个带有 Custom Theme 的示例。

public ShellView()
{
    this.InitializeComponent();
    ThemeManager.AddAccent("YourAccent", new Uri("pack://application:,,,/YourAccent.xaml"));

    // Set your Custom Theme when the Window start
    var theme = ThemeManager.DetectAppStyle(Application.Current);
    ThemeManager.ChangeAppStyle(Application.Current, ThemeManager.GetAccent("YourAccent"), theme.Item1);
}

private void Button_Click(object sender, RoutedEventArgs e)
{
    // Change the Theme to Cyan on a simple button click
    var theme = ThemeManager.DetectAppStyle(Application.Current);
    ThemeManager.ChangeAppStyle(Application.Current, ThemeManager.GetAccent("Cyan"), theme.Item1);
}

我认为你有 2 个选项可以解决这个问题。

  • 创建 Test.UCDemo 作为 VMDemo 类型的 DataTemplate 并将此模板的 VMDemo 传递给 Content,这样您的 ContentControl 将自动为你施展魔法(这只是一个建议,我没有测试过)
  • 也将资源放入您的Test.UCDemo