在这里,我使用 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;
}
请解释一下它的作用。如果你需要整个课程代码,我会给它。