1

ここでは、パートナーがクラス CommandBindingExtension を使用する mvvm を使用しています。これは、IProvideValueTarget と IServiceProvider の役割を理解できるためです。

[MarkupExtensionReturnType(typeof(ICommand))]
public class CommandBindingExtension : MarkupExtension
{
    public CommandBindingExtension(string commandName)
    {
        this.CommandName = commandName;
    }

    [ConstructorArgument("commandName")]
    public string CommandName { get; set; }

    private object targetObject;
    private object targetProperty;

    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        IProvideValueTarget provideValueTarget = serviceProvider.GetService(typeof(IProvideValueTarget)) as IProvideValueTarget;
        if (provideValueTarget != null)
        {
            targetObject = provideValueTarget.TargetObject;
            targetProperty = provideValueTarget.TargetProperty;
        }

        if (!string.IsNullOrEmpty(CommandName))
        {
            // The serviceProvider is actually a ProvideValueServiceProvider, which has a private field "_context" of type ParserContext
            ParserContext parserContext = GetPrivateFieldValue<ParserContext>(serviceProvider, "_context");
            if (parserContext != null)
            {
                // A ParserContext has a private field "_rootElement", which returns the root element of the XAML file
                FrameworkElement rootElement = GetPrivateFieldValue<FrameworkElement>(parserContext, "_rootElement");
                if (rootElement != null)
                {
                    // Now we can retrieve the DataContext
                    object dataContext = rootElement.DataContext;

                    // The DataContext may not be set yet when the FrameworkElement is first created, and it may change afterwards,
                    // so we handle the DataContextChanged event to update the Command when needed
                    if (!dataContextChangeHandlerSet)
                    {
                        rootElement.DataContextChanged += new DependencyPropertyChangedEventHandler(rootElement_DataContextChanged);
                        dataContextChangeHandlerSet = true;
                    }

                    if (dataContext != null)
                    {
                        ICommand command = GetCommand(dataContext, CommandName);
                        if (command != null)
                            return command;
                    }
                }
            }
        }

        // The Command property of an InputBinding cannot be null, so we return a dummy extension instead
        return DummyCommand.Instance;
    }

それの役割を説明してください.クラス全体のコードが必要な場合は、私が与えるよりも.

4

1 に答える 1

1

IProvideValueTargetは、サービスプロバイダーがこのコンテキストで提供できるサービスの1つです。これらのサービスの詳細については、 MSDNを参照してください。

タイプコンバーターとマークアップ拡張機能の使用法をサポートするタイプの作成者は、多くの場合、使用法がマークアップ内または周囲のオブジェクトグラフ構造内のどこにあるかについてのコンテキスト情報を持っている必要があります。提供されたオブジェクトが正しくインスタンス化されるため、またはオブジェクトグラフ内の既存のオブジェクトへのオブジェクト参照を作成できるようにするために、情報が必要になる場合があります。.NET Framework XAMLサービスを使用する場合、必要になる可能性のあるコンテキストは一連のサービスインターフェイスとして公開されます。

マークアップ拡張またはタイプコンバータの実装に使用できるサービスは、各仮想メソッドのシグネチャの一部であるコンテキストパラメータを介して通信されます。いずれの場合も、コンテキストにIServiceProviderが実装されており、IServiceProvider.GetServiceを呼び出してサービスを要求できます。

于 2012-05-18T10:38:32.427 に答える