7

MV-VMパターンを使用しています

私のVMには次のようなコードがあります

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>

(マークアップ拡張機能を使用するたびにパラメーターとして入力する必要がないようにするため)

現在、マークアップ拡張機能で Document 添付プロパティを読み取ろうとすると、常に null ドキュメントが取得されます。バインドをデバッグすると、マークアップ拡張機能の実行後に添付プロパティが適切な値を取得するタイミングの問題のように見えます。

これを何らかの形で機能させることは可能ですか?

4

2 に答える 2

7

ProvideValue メソッドは 2 回呼び出されます。1 回は XAML がパーサーによって評価されるとき、もう 1 回は値が読み込まれるときです。この最初の呼び出しでは、targetObject は単なる SharedDP と呼ばれる一種のダミー オブジェクトであり、マークアップ拡張が適用されるオブジェクトではありません。この最初の呼び出しをスキップして、2 番目の呼び出しのみを処理する必要があります。これは、アプリで動作するコードです。

   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; 


    }
于 2010-07-17T00:36:09.453 に答える
1

おそらく、マークアップ拡張機能からページの Loaded または Initialized イベントにイベントを接続できます。または、Foo.Document が言及された後に、XAML ファイルにマークアップ拡張機能を配置することもできます。

ありがとう、Rob Relyea WPF/XAML チーム のブログ

于 2009-06-03T17:50:29.823 に答える