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

时间:2013-11-21 11:18:46

标签: c# wpf properties grid children

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

例如:我有一个TextBox

<TextBox Height="150"/>

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

3 个答案:

答案 0 :(得分:0)

您可以在自己的代码中继承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

属性已更改:Instance 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

属性已更改:ActualWidth 509

属性已更改:ActualHeight 150

属性已更改:PageHeight 148

答案 1 :(得分:0)

这是一个具有挑战性的问题,但幸运的是,我喜欢挑战。所以最初,我找到了DependencyPropertyHelper.GetValueSource method。此方法需要DependencyObjectDependencyProperty并返回ValueSource struct

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

ValueSource struct具有BaseValueSource enum属性,其中包含以下成员:

enter image description here

这些值与DependencyProperty优先级列表相关,并指定可以更改DependencyProperty值的不同方式。 BaseValueSource enum实例值Local表示该属性是使用SetValue方法在本地设置的...此还包含已设置属性的实例使用SetValue方法的代码。 Framework使用此方法从XAML标记设置值。

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

快速搜索后,我在StackOverflow上的List properties of a DependencyObject?帖子中找到了使用DependencyPropertyHelper的方法。但是,我一直在寻找,然后遇到了一个更好的方法... 很多更好的方法。我在Visual Studio论坛的Getting list of all dependency/attached properties of an Object问题中找到了它。

如果你在周勇的答案中向下看那页,你可以找到他创建的DependencyPropertyHelper.GetValueSource课程。起初我想'让我运行这个DependencyProperty方法来看看我得到了什么',并期待TextBlock的所有MarkupObject的长列表。

然而,事实证明,这种方法产生的正是你所追求的。它仅返回实际上已在XAML中设置的属性。在他的代码中,我看到了MarkupPropertyMarkupWriterTextBlock。我之前没有使用过这些,但似乎这实际上是在查看为ValueSource struct定义的XAML。所以在帮助你的过程中,我实际上也学到了一些新东西...... +1好问题。

请记住,我相信您可以忽略我关于{{1}}的答案的早期部分,并且只使用该方法。如果您需要更多帮助,请告诉我。

答案 2 :(得分:0)

基于Sheridan的link提供的answer,这是在XAML中获取元素上所有属性设置所需的非常小的代码段:

MarkupWriter.GetMarkupObjectFor(element).Properties