获取特定 TargetType 的样式列表

发布于 2024-12-09 09:47:53 字数 235 浏览 4 评论 0原文

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

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

I want to attain a list of styles that apply to a specific control type. I'd like to do something like the code below, but not have to specify a key name and get a list of applicable resources back. Is this possible?

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

迷迭香的记忆 2024-12-16 09:47:53

首先检查控件的 Resources,然后继续沿 VisualTree 向上检查 Resources 来模拟 WPF 的工作方式是否有意义找到您的控件的资源(包括样式)?

例如,也许您可​​以创建一个扩展方法,在给定 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 的 XAML 文件在 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());
}

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

Would it make sense to first examine the Resources of your control, and then continue walking up the VisualTree examining Resources along the way to simulate how WPF finds resources for your control (including Styles)?

For example, maybe you could create an extension method that does this given a 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;
        }
    }
}

To see that this works, create XAML file that has both implicit and explicit Styles at multiple levels in the 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>

and with the following handler in the code behind:

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

In this example, 4 styles are found for the myButton all of which have a TargetType of Button. I hope this can be a good starting point. Cheers!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文