简体   繁体   中英

How can I include my custom user control with its custom view model into my xaml view?

I'd have a little question on prism / xaml in general. If someone has a clue, I'd be happy to know about it.

I made up a standard Prism application with a Prism module (Prism 6.3.0). There I have a main view consisting of the following code:

<!-- MainView.xaml -->
<UserControl prism:ViewModelLocator.AutoWireViewModel="True"
             ...>
[...]
    <dxb:BarManager>
        [...]
            <local:MyUserControl/>
        [...]
    </dxb:BarManager>
</UserControl>

In that view, you notice

<local:MyUserControl/>

That thing is implemented as follows:

<!-- MyUserControl.xaml -->

<dxr:RibbonPageGroup x:Class="MyUserControl" ...>
    [...]

    <dxb:BarButtonItem Content="Import"
                       Command="{Binding ImportDataCommand}" />
    [...]
</dxr:RibbonPageGroup>

and

// MyUserControl.xaml.cs
public partial class MyUserControl
{
    public MyUserControl()
    {
        InitializeComponent();
    }
}

Now, the idea is that MyUserControl uses its own view model, because it needs to contain special logic related to that particular control. All that logic is defined by an interface IMyUserControlViewModel , which I would like to inject into the MyUserControl and make it available as its DataContext . Of course, MyUserControlViewModel , which implements IMyUserControlViewModel and which I want to inject into the view, has dependencies in services. How can I wire that up? I tried many things without success. I am well-aware of these advanced ways of wiring up and these basic ways of wiring up . My guess is that it is not possible because, in the MainView.xaml , we use

prism:ViewModelLocator.AutoWireViewModel="True"

Am I seeing that right? If not, how can make my idea happen? Is it possible to do without changing the ViewModelLocator 's configuration, as explained here ? In the project I am working for, they want to stick to automatic view model wiring for some obscure reasons. Is there a way to override the automatic view model wiring in the module initialization code? The module initialization code I am talking about is something like

public class MyModule : IModule
{
    private readonly IUnityContainer _container;
    private readonly IRegionManager _regionManager;

    public MyModule (IUnityContainer container, IRegionManager regionManager)
    {
        _container = container;
        _regionManager = regionManager;
    }

    public void Initialize()
    {
        //_container.RegisterType<>();

       _regionManager.AddToRegion(RegionNames.MainRegion, ServiceLocator.Current.GetInstance<MainView>());
    }
}

As a general rule, try to go view model first, if you can, as it makes things easier and clearer.

So in your case, instead of

<UserControl prism:ViewModelLocator.AutoWireViewModel="True">
    <dxb:BarManager>
        <local:MyUserControl/>
    </dxb:BarManager>
</UserControl>

do

<UserControl prism:ViewModelLocator.AutoWireViewModel="True">
    <dxb:BarManager>
        <ContentControl Content={Binding SpecialViewModel}/>
    </dxb:BarManager>
</UserControl>

with a DataTemplate that maps IMyUserControlViewModel to MyUserControl and expose an instance of the sub-view model from your view model. This way, you can use a specialized instance, tailored for the use case at hand without having to jump through loops just to please the ViewModelLocator .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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