简体   繁体   English

如何从MarkupExtension返回强类型对象?

[英]How to return strongly typed object from MarkupExtension?

Trying to make my first ever MarkupExtension, as a Service Locator and use it to get the DataContext in my XAML : 尝试使我的第一个MarkupExtension作为服务定位器,并使用它来获取XAML中的DataContext:

ViewModel & Interface ViewModel和接口

public interface IMainViewModel
{
    ICommand OpenProjectCommand { get; }
}

public class MainViewModel : IMainViewModel
{
    public ICommand OpenProjectCommand { get; private set; }
    ...
}

Service Locator : 服务定位器:

public static class ServiceLocator
{
    public static void Map<T>(object concreteType)
    {
        // store type
    }

    public static T GetInstance<T>() where T : class
    {
        // get, instantiate and return
    }
}

App.xaml App.xaml中

protected override void OnStartup(StartupEventArgs e)
{
    ServiceLocator.Map<IMainViewModel>(typeof(MainViewModel));
    base.OnStartup(e);  
}

MarkupExtension: 的MarkupExtension:

public class ServiceLocatorExtension : MarkupExtension
{
    public Type ServiceType { get; set; }

    public ServiceLocatorExtension(Type type)
    {
        ServiceType = type;
    }

    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        if (ServiceType == null)
            throw new ArgumentException("Type argument is not specified");

        var instance = ServiceLocator.GetInstance<IMainViewModel>(); // how to use this.ServiceType?
        return instance;
    }
}

XAML: XAML:

<Window ... DataContext="{loc:ServiceLocator {x:Type loc:IMainViewModel}}">
...
<Button ... Command="{Binding OpenProjectCommand}"/> // problem complains cannot resolve in datacontext type of "object"

Questions: 问题:

1) How can I use this.ServiceType property in the MarkupExtension instead of the explicit interface? 1)如何在MarkupExtension中使用this.ServiceType属性而不是显式接口?

2) The command binding on the button in XAML complains it cannot resolve from a datacontext of type object, so I get a warning, which I do not want. 2)XAML中按钮上的命令绑定抱怨它无法从类型为object的数据上下文中解析,因此我得到了警告,我不希望这样做。 How to I make it know its correct type? 我如何知道它的正确类型?

Not sure if this is the best solution, still looking for alternatives. 不确定这是否是最佳解决方案,仍在寻找替代方案。

1: 1:

Using reflection: 使用反射:

public override object ProvideValue(IServiceProvider serviceProvider)
{
    if (ServiceType == null)
        throw new ArgumentException("Type argument is not specified");

    var serviceLocatorMethod = typeof(ServiceLocator).GetMethod("GetInstance").MakeGenericMethod(ServiceType);
    return serviceLocatorMethod.Invoke(null, null);
}

2: 2:

As its a designer issue, this solves the problem: 作为设计者,这可以解决问题:

d:DataContext="{d:DesignInstance loc:MainViewModel}"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM