c# - IProvideValueTarget和IServiceProvider有什么区别?

标签 c# wpf mvvm

在这里,我正在使用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;
    }

请解释一下它的作用。如果您需要整个类的代码,我会给出。

最佳答案

IProvideValueTarget service provider在此上下文中可以提供的服务之一。有关这些服务的更多信息,请参见MSDN

Authors of the types that support type converter and markup extension usages must often have contextual information about where a usage is located in the markup, or in surrounding object graph structure. Information might be needed so that the provided object is instantiated correctly or so that object references to existing objects in the object graph can be made. When using .NET Framework XAML Services, the context that might be required is exposed as a series of service interfaces.



The services available for a markup extension or type converter implementation are communicated through the context parameters that are part of the signature of each virtual method. In every case, you have IServiceProvider implemented in the context, and can call IServiceProvider.GetService to request a service.

关于c# - IProvideValueTarget和IServiceProvider有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10651027/

相关文章:

wpf - WPF错误处理多语言

c# - 如何将时间跨度转换为下午或上午时间?

c# - 如何检测何时按下向下箭头键/C# WPF

c# - MVC RoleProvider 和 Authorize 属性

c# - Prism 单实例 View 模型,由多个 View 使用

c# - MVVM模式是否适合此应用程序的要求?

mvvm - 6 个 ViewModel 和一个 Messenger 之间的通信 == AntiPattern?

c# - 将组合框绑定(bind)到模型/ View 模型

c# - ASP.NET Page_Unload 阻止用户离开页面

c# - 使用泛型 T 的 DefineMethod