HandyControl 解决不全局引入控件部分内容不显示问题
问题场景
使用HandyControl
时并不按照官方文档方式,在App.xaml
中添加以下代码:
<Application.Resources><ResourceDictionary><ResourceDictionary.MergedDictionaries><ResourceDictionary Source="pack://application:,,,/HandyControl;component/Themes/SkinDefault.xaml"/><ResourceDictionary Source="pack://application:,,,/HandyControl;component/Themes/Theme.xaml"/></ResourceDictionary.MergedDictionaries></ResourceDictionary>
</Application.Resources>
而只是在必要窗口页面引入SkinDefault.xaml
和Theme.xaml
,导致部分控件样式丢失,常见的例如Growl
。
页面代码如下:
<Window x:Class="WPFResource.MainWindow"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"xmlns:local="clr-namespace:WPFResource"xmlns:hc="https://handyorg.github.io/handycontrol"mc:Ignorable="d"Title="MainWindow" Height="450" Width="800"><DockPanel><Button Content="Click" Click="Button_Click" DockPanel.Dock="Top"></Button><ScrollViewer VerticalScrollBarVisibility="Hidden" HorizontalAlignment="Right"><ScrollViewer.Resources><ResourceDictionary><!--希望在这里引入控件样式--><ResourceDictionary.MergedDictionaries><ResourceDictionary Source="pack://application:,,,/HandyControl;component/Themes/SkinDefault.xaml"></ResourceDictionary><ResourceDictionary Source="pack://application:,,,/HandyControl;component/Themes/Theme.xaml"></ResourceDictionary></ResourceDictionary.MergedDictionaries></ResourceDictionary></ScrollViewer.Resources><StackPanel hc:Growl.GrowlParent="True" VerticalAlignment="Top" Margin="0,10,10,10"/></ScrollViewer></DockPanel>
</Window>
页面后端代码:
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : System.Windows.Window
{public MainWindow(){InitializeComponent();}private void Button_Click(object sender, RoutedEventArgs e){// 点击弹出GrowlInfo信息Growl.Success("HHHHHHHHHH");}
}
运行效果如图一,并不是期望效果图二,图一缺少了图标。
解决方案
通过查看Growl
对应的控件代码,可以知道,构建Growl
控件实例时,图标实际为Geometry
类型,只有Icon
与 IconBrush
两者为null 会导致图标出来,进而查看ResourceHelper.GetResource()
。
var ctl = new Growl
{Message = growlInfo.Message,Time = DateTime.Now,Icon = ResourceHelper.GetResource<Geometry>(growlInfo.IconKey) ?? growlInfo.Icon,//读取资源,也可以采用手动为growlInfo实例添加自定义图标IconBrush = ResourceHelper.GetResource<Brush>(growlInfo.IconBrushKey) ?? growlInfo.IconBrush,//读取资源,也可以采用手动为growlInfo实例添加自定义图标画刷_showCloseButton = growlInfo.ShowCloseButton,ActionBeforeClose = growlInfo.ActionBeforeClose,_staysOpen = growlInfo.StaysOpen,ShowDateTime = growlInfo.ShowDateTime,ConfirmStr = growlInfo.ConfirmStr,CancelStr = growlInfo.CancelStr,Type = growlInfo.Type,_waitTime = Math.Max(growlInfo.WaitTime, MinWaitTime)
};
对应代码实现如下,获取资源并不是通过当前窗口实例进行资源获取,上级也不存在必要的图标和笔刷,故而缺少资源就会返回null
:
/// <summary>
/// 资源帮助类
/// </summary>
public class ResourceHelper
{/// <summary>/// 获取资源/// </summary>/// <param name="key"></param>/// <returns></returns>public static T GetResource<T>(string key){if (Application.Current.TryFindResource(key) is T resource){return resource;}return default;}
}
缺少那就引入,好在HandyControl
的基础资源比较规范,提供了一套相对比较完整的资源文件。
这些资源在src/Shared/HandyControl_Shared/Themes/Basic
中。
\Themes\Basic
│ Behaviors.xaml
│ Brushes.xaml
│ Converters.xaml
│ Effects.xaml
│ Fonts.xaml
│ Geometries.xaml
│ Paths.xaml
│ Sizes.xaml
└─ColorsColors.xamlColorsDark.xamlColorsViolet.xaml
解决办法如下:
本地项目中创建Themes
目录同时创建Themes/Basic
目录,需要注意的是,文件属性需要设置为页
。
└─Themes└─Basic│ Brushes.xaml│ Geometries.xaml└─ColorsColors.xaml
在App.xaml
中进行引入本地资源,程序集为当前项目名称,此处为WPFResource
。
<Application x:Class="WPFResource.App"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:local="clr-namespace:WPFResource"StartupUri="MainWindow.xaml"><Application.Resources><ResourceDictionary><ResourceDictionary.MergedDictionaries><ResourceDictionary Source="pack://application:,,,/WPFResource;component/Themes/Basic/Colors/Colors.xaml"></ResourceDictionary><ResourceDictionary Source="pack://application:,,,/WPFResource;component/Themes/Basic/Brushes.xaml"/><ResourceDictionary Source="pack://application:,,,/WPFResource;component/Themes/Basic/Geometries.xaml"/></ResourceDictionary.MergedDictionaries></ResourceDictionary></Application.Resources>
</Application>
运行效果如下: