2013-11-21 76 views
2

我有一個網格的孩子循環。對於每個孩子,我想知道在XAML代碼中明確指定了哪些屬性。我有機會找出答案嗎?如何從xaml獲得明確的指定屬性

例如:我有一個TextBox

<TextBox Height="150"/> 

只有財產高度由XAML碼給出。我怎麼能在C#代碼中找到它? 換句話說,我不想要TextBox的所有屬性,但只需要在XAML中指定的那些屬性。

+0

它有點怪異。您將需要XAMLReader來執行此操作。看看這個鏈接:http://msdn.microsoft.com/en-us/library/system.xaml.xamlreader%28v=vs.110%29.aspx –

+0

[Snoop](http://snoopwpf.codeplex 。com /)在運行時知道屬性的值是否來自Style/Template/Local /等。無需訪問原始XAML文件。我會在snoop的代碼中挖掘一下,看看我能否發現它是如何完成的。您正在尋找具有由「本地」設置的值的屬性。 – XAMeLi

+0

Thx爲您的答案!我不想使用閱讀器閱讀XAML代碼。也許Snoop也使用XmlReader ...我不知道。但看起來並不那麼容易。 – peter70

回答

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

改變性質:實例System.Windows.Documents.TextEditor

已更改屬性:XmlnsDictionary System.Windows.Markup.XmlnsDict ionary

改變性質:IWindowService WpfApplication1.MainWindow

屬性改變:名稱TB

改變性質:身高150

改變性質:背景#FFFFFFFF

改變性質:BorderBrush#FFABADB3

已更改:前景#FF000000

屬性更改:了borderThickness 1,1,1,1

改變性質:TabNavigation無

改變性質:FocusVisualStyle

屬性改變:真正的AllowDrop

改變性質:PanningMode VerticalFirst

已更改:IsFlicksEnabled False

改變性質:模板System.Windows.Controls.ControlTemplate

改變性質:XmlNamespaceMaps System.Collections.Hashtable

改變性質:XmlnsDictionary中System.Windows.Markup.XmlnsDictionary

改變性質:XmlNamespaceMaps系統.Collections。哈希表

屬性改變:可見性真

改變性質:ActualWidth的509

屬性改變:的ActualHeight 150

改變性質:PageHeight 148

0

這是一個具有挑戰性的問題,但幸運的是你,我喜歡一個很好的挑戰。所以最初,我找到了DependencyPropertyHelper.GetValueSource method。此方法需要一個DependencyObjectDependencyProperty並返回一個ValueSource struct

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

ValueSource struct具有具有以下成員的BaseValueSource enum屬性:

enter image description here

這些值涉及的DependencyProperty優先級列表並指定DependencyProperty值可以更改的不同方式。 A BaseValueSource enum實例值Local表示該屬性是使用SetValue方法在本地設置的......此也包括使用SetValue方法在代碼中設置屬性的實例。框架使用此方法從XAML標記中設置值。

唯一的問題是,我們現在不得不找到所有的DependencyProperty個特定DependencyObject,使我們可以調用上述方法在每個集合,看它是否是由SetValue方法設置。我希望微軟能給我們一些東西來爲我們做這件事,但似乎沒有。

經過快速搜索,我找到了一種方法,在StackOverflow的List properties of a DependencyObject?這篇文章中使用Reflection。但是,我一直在尋找,然後碰到更好的方法...一個更好的方法。我在Visual Studio論壇的Getting list of all dependency/attached properties of an Object問題中發現它。

如果你在周永的回答中往下看,你可以找到他創建的DependencyPropertyHelper類。起初,我想'讓我來運行這個DependencyPropertyHelper.GetValueSource方法來看看我得到了什麼',並期待TextBlock的所有DependencyProperty的長列表。

然而,事實證明,這種方法的結果正是你所追求的。它僅返回實際已在XAML中設置的屬性。在他的代碼中,我看到一個MarkupObject,一個MarkupProperty和一個MarkupWriter。我以前沒有用過這些,但看起來這實際上是在爲TextBlock定義的XAML。所以在幫助你,我實際上也學到了一些新東西...... +1好問題。

考慮到這一點,我相信你可以忽略我的回答的前面部分關於ValueSource struct,只是使用該方法。讓我知道如果你需要更多的幫助。