简体   繁体   English

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

[英]How to get explicit specified properties from xaml

I have a loop with children of a grid.我有一个带有网格子元素的循环。 For every child, I want to know which properties have been specified explicitly in the XAML code.对于每个孩子,我想知道在 XAML 代码中明确指定了哪些属性。 Do I have a chance to find out?我有机会知道吗?

For example: I have a TextBox例如:我有一个文本框

<TextBox Height="150"/>

Only the property Height is given by XAML-Code. XAML-Code 仅提供属性 Height。 How I can find it out in the c# Code?我如何在 c# 代码中找到它? In other words, I don't want all of the properties of the TextBox, but only those who are specified in the XAML.换句话说,我不想要 TextBox 的所有属性,而只想要 XAML 中指定的那些属性。

This was a challenging question, but luckily for you, I like a good challenge.这是一个具有挑战性的问题,但对你来说幸运的是,我喜欢一个很好的挑战。 So initially, I found the DependencyPropertyHelper.GetValueSource method .所以最初,我找到了DependencyPropertyHelper.GetValueSource方法 This method takes a DependencyObject and a DependencyProperty and returns a ValueSource struct :此方法接受一个DependencyObject和一个DependencyProperty并返回一个ValueSource struct

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

The ValueSource struct has a BaseValueSource enum property which has the following members: ValueSource struct具有BaseValueSource enum属性,该属性具有以下成员:

在此处输入图片说明

These values relate to the list of DependencyProperty precedences and specify the different ways that a DependencyProperty value can be changed.这些值与DependencyProperty优先级列表DependencyProperty并指定可以更改DependencyProperty值的不同方式。 A BaseValueSource enum instance value of Local means that the property was set locally using the SetValue method... this will also include instances where a property was set in code using the SetValue method. Local BaseValueSource enum实例值意味着该属性是使用SetValue方法在本地设置的……这还将包括使用SetValue方法在代码中设置属性的实例。 The Framework uses this method to set values from XAML markup.框架使用此方法从 XAML 标记设置值。

The only problem was that we'd now have to find a collection of all of the DependencyProperty s of a particular DependencyObject so that we could call the above method on each to see if it was set by the SetValue method.唯一的问题是,我们现在必须找到特定DependencyObject的所有DependencyProperty的集合,以便我们可以对每个对象调用上述方法以查看它是否由SetValue方法设置。 I was hoping that Microsoft would have given us something to do this for us, but it appears not.我希望微软能给我们一些东西来为我们做这件事,但似乎没有。

After a quick search, I found a way to do this using Reflection in the List properties of a DependencyObject?快速搜索后,我找到了一种在DependencyObjectList 属性中使用Reflection来执行此操作的方法 post here on StackOverflow.在 StackOverflow 上发帖。 However, I kept looking and then came across a better method... a much better method.不过,我一直在寻找,然后跨过一个更好的方法......一个更好的方法来。 I found it in the Getting list of all dependency/attached properties of an Object question on the Visual Studio Forum.我在 Visual Studio 论坛上的对象问题的所有依赖项/附加属性获取列表中找到了它。

If you look down that page at the answer from Zhou Yong, you can find a DependencyPropertyHelper class that he created.如果您在该页面上查看 Zhou Yong 的回答,您可以找到他创建的DependencyPropertyHelper类。 At first I thought 'let me just run this DependencyPropertyHelper.GetValueSource method to see what I get' and was expecting a long list of all of the DependencyProperty s of the TextBlock .起初我想“让我运行这个DependencyPropertyHelper.GetValueSource方法来看看我得到了什么”,并期待一长串TextBlock的所有DependencyProperty的列表。

However, it turns out that what comes out of this method is exactly what you're after.然而,事实证明,这种方法的结果正是您所追求的。 It only returns the properties that have actually been set in XAML .它只返回在 XAML 中实际设置的属性。 In his code, I see a MarkupObject , a MarkupProperty and a MarkupWriter .在他的代码中,我看到了一个MarkupObject 、一个MarkupProperty和一个MarkupWriter I've not used these before, but it seems that this is actually looking at the XAML defined for the TextBlock .我以前没有使用过这些,但似乎这实际上是在查看为TextBlock定义的 XAML。 So in helping you, I've actually learned some new things too... +1 good question.因此,在帮助您的过程中,我实际上也学到了一些新东西... +1 好问题。

Bearing that in mind, I believe that you can ignore the earlier part of my answer regarding the ValueSource struct and just use that method.牢记这一点,我相信您可以忽略我前面关于ValueSource struct答案,而只需使用该方法。 Let me know If you need any more help.如果您需要更多帮助,请告诉我。

You could inherit the TextBox in your own code.您可以在自己的代码中继承 TextBox。 The PropertyChanged could then be overriden and you would receive any properties changing.然后可以覆盖 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>

Unfortunatly you will also receive properties changed by styles不幸的是,您还会收到由样式更改的属性

Here's the result of the code above这是上面代码的结果

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

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

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

Property changed: IWindowService WpfApplication1.MainWindow属性更改:IWindowService WpfApplication1.MainWindow

Property changed: Name TB属性已更改:名称 TB

Property changed: Height 150属性更改:高度 150

Property changed: Background #FFFFFFFF属性更改:背景#FFFFFFFF

Property changed: BorderBrush #FFABADB3属性更改:BorderBrush #FFABADB3

Property changed: Foreground #FF000000属性更改:前景#FF000000

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

Property changed: TabNavigation None属性已更改:TabNavigation 无

Property changed: FocusVisualStyle属性已更改:FocusVisualStyle

Property changed: AllowDrop True属性更改:AllowDrop True

Property changed: PanningMode VerticalFirst属性已更改:PanningMode VerticalFirst

Property changed: IsFlicksEnabled False属性已更改:IsFlicksEnabled False

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

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

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

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

Property changed: IsVisible True属性更改:IsVisible True

Property changed: ActualWidth 509属性更改:实际宽度 509

Property changed: ActualHeight 150属性更改:实际高度 150

Property changed: PageHeight 148属性更改:PageHeight 148

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

MarkupWriter.GetMarkupObjectFor(element).Properties

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

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