1

在这里,我使用 mvvm。因为我的合作伙伴使用类 CommandBindingExtension,因为我可以理解 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服务提供者在这种情况下可以提供的服务之一。有关这些服务的更多信息,请参阅MSDN

支持类型转换器和标记扩展用法的类型的作者通常必须具有有关用法在标记中或周围对象图结构中的位置的上下文信息。可能需要信息,以便正确实例化所提供的对象,或者可以对对象图中的现有对象进行对象引用。使用 .NET Framework XAML 服务时,可能需要的上下文公开为一系列服务接口。

可用于标记扩展或类型转换器实现的服务通过上下文参数进行通信,这些参数是每个虚拟方法签名的一部分。在每种情况下,您都在上下文中实现了 IServiceProvider,并且可以调用 IServiceProvider.GetService 来请求服务。

于 2012-05-18T10:38:32.427 回答