wpf 获取用于在XAML中设置属性值的资源的键

au9on6nz  于 2023-03-24  发布在  其他
关注(0)|答案(2)|浏览(143)

假设我在XAML中定义了WPF窗口:

<Window x:Class="OINA.Papyrus.ReportGeneratorPoCNetv48.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:OINA.Papyrus.ReportGeneratorPoCNetv48"
        xmlns:system="clr-namespace:System;assembly=mscorlib"
        mc:Ignorable="d"
        Title="MainWindow" Height="200" Width="800">
    <StackPanel Margin="20" Loaded="OnLoaded">
        <StackPanel.Resources>
            <system:String x:Key="Greeting">Hello, World!</system:String>
            <system:String x:Key="Farewell">Goodbye, World!</system:String>
        </StackPanel.Resources>
        <TextBlock x:Name="myTextBlock" Text="{StaticResource Greeting}" />
    </StackPanel>
</Window>

TextBlock元素有一个值为“Hello,World!"的Text属性,因此在代码隐藏中我们可以简单地执行myTextBlock.Text。但是,除了获取Text属性的值之外,是否有一种方法可以确定用于提供Text属性值的资源的键,在上面的例子中是“问候”

zpjtge22

zpjtge221#

您需要一个地方来存储有关密钥的信息。附加属性非常适合。

class AP : DependencyObject
{
    public static string GetResourceKey(DependencyObject obj)
    {
        return (string)obj.GetValue(ResourceKeyProperty);
    }
    public static void SetResourceKey(DependencyObject obj,
       string value)
    {
        obj.SetValue(ResourceKeyProperty, value);
    }

    public static readonly DependencyProperty ResourceKeyProperty =
          DependencyProperty.RegisterAttached("ResourceKey", typeof(string), typeof(AP));

}

然后,您需要一种方法来使资源检索可行并存储键值。为此,请创建一个自定义标记扩展。在中,您调用常规静态资源并将key的值分配给附加属性。

class StaticResourceWithkeyMarkup : MarkupExtension
{
    public string Key { get; set; } 

    public override object ProvideValue(IServiceProvider serviceProvider)
    { 
        var target = serviceProvider.GetService(typeof(IProvideValueTarget)) as IProvideValueTarget;
        var uiElement = target.TargetObject as DependencyObject;
        AP.SetResourceKey(uiElement, Key);
        var staticResource = new StaticResourceExtension(Key); 
        return staticResource.ProvideValue(serviceProvider);
    }
}

该视图如下所示

<StackPanel Margin="20">
    <StackPanel.Resources>
        <system:String x:Key="Greeting">Hello, World!</system:String>
        <system:String x:Key="Farewell">Goodbye, World!</system:String>
    </StackPanel.Resources>
    <TextBlock x:Name="myTextBlock" Text="{local:StaticResourceWithkeyMarkup Key=Farewell}" />
    <Button Content="Click" Click="Button_Click"/>
</StackPanel>

通过检查textBlock附加属性来检索密钥

private void Button_Click(object sender, RoutedEventArgs e)
 {
    var key = AP.GetResourceKey(myTextBlock);
 }
dkqlctbz

dkqlctbz2#

是否有一种方法可以确定用于提供Text属性值的资源的键?
不可以。这些值已经被查找过了,并且到Greeting资源的“连接”没有存储在某个地方。
什么是DynamicResource?
然后你可以试试这个:

var converter = new ResourceReferenceExpressionConverter();
var value = myTextBlock.ReadLocalValue(TextBlock.TextProperty);
var dynamicResource = new ResourceReferenceExpressionConverter()
    .ConvertTo(value, typeof(MarkupExtension)) as DynamicResourceExtension;
string key = dynamicResource.ResourceKey as string;

相关问题