繁体   English   中英

如何从 xaml 获取显式指定的属性

[英]How to get explicit specified properties from xaml

我有一个带有网格子元素的循环。 对于每个孩子,我想知道在 XAML 代码中明确指定了哪些属性。 我有机会知道吗?

例如:我有一个文本框

<TextBox Height="150"/>

XAML-Code 仅提供属性 Height。 我如何在 c# 代码中找到它? 换句话说,我不想要 TextBox 的所有属性,而只想要 XAML 中指定的那些属性。

这是一个具有挑战性的问题,但对你来说幸运的是,我喜欢一个很好的挑战。 所以最初,我找到了DependencyPropertyHelper.GetValueSource方法 此方法接受一个DependencyObject和一个DependencyProperty并返回一个ValueSource struct

ValueSource valueSource = DependencyPropertyHelper.GetValueSource(SomeTextBlock, 
    TextBlock.TextWrappingProperty);

ValueSource struct具有BaseValueSource enum属性,该属性具有以下成员:

在此处输入图片说明

这些值与DependencyProperty优先级列表DependencyProperty并指定可以更改DependencyProperty值的不同方式。 Local BaseValueSource enum实例值意味着该属性是使用SetValue方法在本地设置的……这还将包括使用SetValue方法在代码中设置属性的实例。 框架使用此方法从 XAML 标记设置值。

唯一的问题是,我们现在必须找到特定DependencyObject的所有DependencyProperty的集合,以便我们可以对每个对象调用上述方法以查看它是否由SetValue方法设置。 我希望微软能给我们一些东西来为我们做这件事,但似乎没有。

快速搜索后,我找到了一种在DependencyObjectList 属性中使用Reflection来执行此操作的方法 在 StackOverflow 上发帖。 不过,我一直在寻找,然后跨过一个更好的方法......一个更好的方法来。 我在 Visual Studio 论坛上的对象问题的所有依赖项/附加属性获取列表中找到了它。

如果您在该页面上查看 Zhou Yong 的回答,您可以找到他创建的DependencyPropertyHelper类。 起初我想“让我运行这个DependencyPropertyHelper.GetValueSource方法来看看我得到了什么”,并期待一长串TextBlock的所有DependencyProperty的列表。

然而,事实证明,这种方法的结果正是您所追求的。 它只返回在 XAML 中实际设置的属性。 在他的代码中,我看到了一个MarkupObject 、一个MarkupProperty和一个MarkupWriter 我以前没有使用过这些,但似乎这实际上是在查看为TextBlock定义的 XAML。 因此,在帮助您的过程中,我实际上也学到了一些新东西... +1 好问题。

牢记这一点,我相信您可以忽略我前面关于ValueSource struct答案,而只需使用该方法。 如果您需要更多帮助,请告诉我。

您可以在自己的代码中继承 TextBox。 然后可以覆盖 PropertyChanged,您将收到任何更改的属性。

public class MyTextBox : TextBox
{
    public MyTextBox()
    {
    }

    protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
    {
        Console.WriteLine(string.Format("Property changed: {0} {1}", e.Property.Name, e.NewValue));

        base.OnPropertyChanged(e);
    }
}

<Window x:Class="WpfApplication1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:WpfApplication1"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <local:MyTextBox x:Name="TB" Height="150"></local:MyTextBox>
</Grid>
</Window>

不幸的是,您还会收到由样式更改的属性

这是上面代码的结果

属性更改:UndoManagerInstance MS.Internal.Documents.UndoManager

属性已更改:实例 System.Windows.Documents.TextEditor

属性已更改:XmlnsDictionary System.Windows.Markup.XmlnsDictionary

属性更改:IWindowService WpfApplication1.MainWindow

属性已更改:名称 TB

属性更改:高度 150

属性更改:背景#FFFFFFFF

属性更改:BorderBrush #FFABADB3

属性更改:前景#FF000000

属性更改:BorderThickness 1,1,1,1

属性已更改:TabNavigation 无

属性已更改:FocusVisualStyle

属性更改:AllowDrop True

属性已更改:PanningMode VerticalFirst

属性已更改:IsFlicksEnabled False

属性已更改:模板 System.Windows.Controls.ControlTemplate

属性已更改:XmlNamespaceMaps System.Collections.Hashtable

属性已更改:XmlnsDictionary System.Windows.Markup.XmlnsDictionary

属性已更改:XmlNamespaceMaps System.Collections.Hashtable

属性更改:IsVisible True

属性更改:实际宽度 509

属性更改:实际高度 150

属性更改:PageHeight 148

根据 Sheridan's answer 中提供的链接,这里是获取 XAML 中元素上设置的所有属性所需的非常小的代码片段:

MarkupWriter.GetMarkupObjectFor(element).Properties

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM