Получение списка стилей определенного типа TargetType - PullRequest
0 голосов
/ 11 октября 2011

Я хочу получить список стилей, которые применяются к определенному типу элемента управления.Я хотел бы сделать что-то вроде приведенного ниже кода, но не обязательно указывать имя ключа и получить список соответствующих ресурсов.Возможно ли это?

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

1 Ответ

1 голос
/ 12 октября 2011

Имеет ли смысл сначала проверить 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;
        }
    }
}

Чтобы убедиться, что это работает, создайте файл XAML, который имеет как неявный, так и явный Styles на нескольких уровнях в VisualTree:

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

В этом примере найдено 4 стиля для myButton все из которых имеют TargetType из Button.Я надеюсь, что это может быть хорошей отправной точкой.Ура!

...