Mahapps主题未应用于用户控件

3
我有一个单一的MetroWindow窗口,加载默认颜色。我提供了一个选项,让用户更改样式。在窗口中,我使用Content控件来在代码后台动态设置用户控件,初始化这个窗口(此窗口是从另一个应用程序初始化的,因此没有app.xaml文件,我在窗口本身中使用资源)。下面是主窗口的代码。在用户控件中,我使用一些标签和选项卡控件。在窗口中,我提供了一个选项,让用户从可用主题中选择更改主题(就像你的演示项目中一样)。在所有标签中,我使用的是动态资源。
当窗口第一次加载时,将应用默认颜色,并且所有内部控件也有相同的主题。当我从窗口顶部更改主题时,窗口边框、标题和发光效果会更改,但内部控件仍然保持旧的主题(如选项卡控件标题等)。我尝试了一切,但似乎没有改变。
以下是我的代码:
    <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>

我的窗口后台代码:

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;
        }
    }
}

最后,这是我如何从托管应用程序代码中调用窗口和嵌入式用户控件的方法:
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;
        }
    }

你能展示一下你的用户控件和后台代码吗? - David
@David:我已经修改了主贴并添加了所有相关代码 - Shankar - Shankar
2个回答

1
我认为你有两个解决方案。
  • 将你的Test.UCDemo创建为VMDemo类型的DataTemplate,并将VMDemo传递给这个模板的Content,这样你的ContentControl就会自动为你完成魔法(这只是一个建议,我没有测试过)。
  • 也可以在你的Test.UCDemo中放置资源。

我正在使用代码。因此,我选择了选项2,并且它有效。谢谢 :) - Shankar
@Shankar,你是怎么解决这个问题的?我也遇到了同样的问题。我已经尝试将所有MahApps资源添加到我的用户控件中,但当我通过ThemeManager更改强调色时,颜色仍然不会更新。 - Andrew Stephens

0

你需要将所有的ResourceDictionaries移动到中。

之后,我认为你需要看一下主题管理器

这是我所做的。在这个例子中,即使我通过按钮点击更改主题,所有我的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);
}

代码需要放在窗口的后台(在我的情况下是ShellView.cs),我会假设它是MainWindow.cs。

这里有另一个例子,使用自定义主题

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);
}

我没有app.xaml文件。这在我的原始帖子中有提到。我的WPF项目是WPF类库,而不是WPF应用程序。我从另一个应用程序调用它。因此,我没有App.xaml。事实上,我没有应用程序对象(Application.Current为空),所以为了更改主题,我使用“ThemeManager.ChangeAppStyle(this, ThemeManager.GetAccent("Cyan"), theme.Item1);”,其中this是窗口对象。我甚至尝试通过代码初始化Application对象(new Application())并添加资源,但也没有成功。 - Shankar
顺便提一下,我正在使用ThemeManager来更改主题,就是上面给出的确切代码。但它只会更改窗口主题,而不是内部ContentControl嵌入的用户控件。 - Shankar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接