这里,我正在使用mvvm .in我的伙伴使用类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;
}
plz解释它的作用是什么。如果你需要全班代码而不是我给它。
答案 0 :(得分:1)
IProvideValueTarget
是service provider在此上下文中可以提供的服务之一。有关这些服务的详细信息,请参阅MSDN。
支持类型转换器和标记扩展使用的类型的作者通常必须具有关于使用在标记中的位置或周围对象图结构中的上下文信息。可能需要信息以便正确地实例化所提供的对象,或者可以对对象图中的现有对象进行对象引用。使用.NET Framework XAML服务时,可能需要的上下文将作为一系列服务接口公开。
可用于标记扩展或类型转换器实现的服务通过作为每个虚拟方法的签名的一部分的上下文参数进行通信。在每种情况下,您都可以在上下文中实现IServiceProvider,并且可以调用IServiceProvider.GetService来请求服务。