2009-06-03 71 views
4

我使用MV-VM模式獲取價值的MarkupExtension

在我的虛擬機我有這樣的代碼

public class ViewModel { 
    public XmlDocument Document { ... } 
    .... 
} 

我有一個標記擴展從中我想用上述文件

public override object ProvideValue(IServiceProvider serviceProvider) { 
     IProvideValueTarget valueProvider = serviceProvider.GetService(typeof(IProvideValueTarget)) as IProvideValueTarget; 
     if (valueProvider != null) { 
      DependencyObject target = valueProvider.TargetObject as DependencyObject; 
      XmlDocument doc = Foo.GetDocument(target); 
      if (doc != null) { 
       var n = doc.SelectSingleNode("/.../text()"); 
       if (n != null) return n.Value; 
      } 
     } 
     return "«" + ObjectProperty + "»"; 
    } 

我創建附加屬性Foo.Document,它連接到我的頁面(頁面的DataContext設置我的ViewModel類的一個實例

<Page ... lc:Foo.Document="{Binding Document}"> 
    ... 
</Page> 

(爲了不必每一個我用的標記擴展的時間把它的類型作爲參數)

現在,在我的標記擴展,當我嘗試讀取文檔附加屬性我總是一個空文件。通過調試綁定,它看起來像是一個計時問題,因爲附加屬性在標記擴展運行後得到適當的值。

是否有可能讓這個工作以某種方式?

回答

1

您可能會將一個事件連接到您的markupextensions頁面上的加載或初始化事件。 或者也許你可以在提到Foo.Document後將你的標記擴展插入到XAML文件中。

謝謝,羅布Relyea WPF/XAML隊 my blog

6

的ProvideValue方法被調用兩次,一次在XAML被分析器評價,並且一旦被加載的值時。在第一次調用時,targetObject只是一種名爲SharedDP的虛擬對象,而不是markupextension應用到的對象。你需要跳過這第一個電話,只處理第二個電話。 這是代碼在我們的應用程序中起作用。

public override object ProvideValue(IServiceProvider serviceProvider){         
       var pvt = serviceProvider as IProvideValueTarget; 
       if (pvt == null) 
       { 
        return null; 
       } 


       var frameworkElement = pvt.TargetObject as FrameworkElement; 
       if (frameworkElement == null) 
       { 
        return this; 
       } 
//.... Code will run once the markup is correctly loaded 
var dataContext = frameworkElement.DataContext; 


    } 
+2

這不爲我所有發生......被調用一次 – flq 2012-03-05 14:03:42