获取特定TargetType的样式列表

时间:2011-10-11 14:54:03

标签: c# wpf resourcedictionary

我想获得适用于特定控件类型的样式列表。我想做类似下面的代码,但不必指定密钥名称并获取适用资源的列表。这可能吗?

ComponentResourceKey key = new ComponentResourceKey(typeof(MyControlType), ""); 
Style style = (Style)Application.Current.TryFindResource(key); 

1 个答案:

答案 0 :(得分:1)

首先检查控件的Resources是否有意义,然后继续沿VisualTree检查Resources向前走,以模拟WPF如何为您的控件找到资源(包括Styles)?

例如,您可以创建一个扩展方法,在FrameworkElement

的情况下执行此操作
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Media;

namespace WpfApplication2
{
    public static class FrameworkElementHelper
    {
        public static IEnumerable<Style> FindStylesOfType<TStyle>(this FrameworkElement frameworkElement)
        {
            IEnumerable<Style> styles = new List<Style>();

            var node = frameworkElement;

            while (node != null)
            {
                styles = styles.Concat(node.Resources.Values.OfType<Style>().Where(i => i.TargetType == typeof(TStyle)));
                node = VisualTreeHelper.GetParent(node) as FrameworkElement;
            }

            return styles;
        }
    }
}

要查看这是否有效,请在Styles中的多个级别创建同时具有隐式VisualTree的XAML文件:

<Window x:Class="WpfApplication2.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:l="clr-namespace:WpfApplication2"
        xmlns:sys="clr-namespace:System;assembly=mscorlib"
        Title="MainWindow" SizeToContent="WidthAndHeight">
    <Window.Resources>
        <Style TargetType="{x:Type Button}" />
        <Style x:Key="NamedButtonStyle" TargetType="{x:Type Button}" />
        <Style TargetType="{x:Type TextBlock}" />
        <Style x:Key="NamedTextBlockStyle" TargetType="{x:Type TextBlock}" />
    </Window.Resources>
    <StackPanel>
        <TextBlock x:Name="myTextBlock" Text="No results yet." />
        <Button x:Name="myButton" Content="Find Styles" Click="OnMyButtonClick">
            <Button.Resources>
                <Style TargetType="{x:Type Button}" />
                <Style x:Key="NamedButtonStyle" TargetType="{x:Type Button}" />
                <Style TargetType="{x:Type TextBlock}" />
                <Style x:Key="NamedTextBlockStyle" TargetType="{x:Type TextBlock}" />
            </Button.Resources>
        </Button>
    </StackPanel>
</Window>

并在后面的代码中使用以下处理程序:

private void OnMyButtonClick(object sender, RoutedEventArgs e)
{
   var styles = myButton.FindStylesOfType<Button>();
   myTextBlock.Text = String.Format("Found {0} styles", styles.Count());
}

在此示例中,找到myButton的4个样式,所有样式的TargetType都为Button。我希望这可以成为一个很好的起点。干杯!