开发者

MVVM access other view's element from viewModel

开发者 https://www.devze.com 2023-04-06 14:51 出处:网络
I started working with the MVVM pattern in a new project. Everything is ok, but i came to the following problem.

I started working with the MVVM pattern in a new project. Everything is ok, but i came to the following problem. The implementation looks like this: I have a MainView, the main app window. In this window开发者_如何学C i have a telerik RadGroupPanel in wich I host the rest of the app views as tabs. The rest of the viewModels does not know about this RadGroupPanel which is hosted in MainVIew. How should i correctly add those views to the RadGroupPanel from the commands in the viewModels? Thanks.


Have you considered injecting your view into the ViewModel using an interface to maintain separation? I know this breaks MVVM but I've successfully used this on a number of WPF projects. I call it MiVVM or Model Interface-to-View ViewModel.

The pattern is simple. Your Usercontrol should have an interface, call it IView. Then in the ViewModel you have a property with a setter of type IMyView, say

public IMyView InjectedView { set { _injectedView = value; } }

Then in the view you create a dependency property called This

public MyUserControl : IMyView
{
    public static readonly DependencyProperty ThisProperty = 
         DependencyProperty.Register("This", typeof(IMyView), typeof(MyUserControl)); 

    public MyUserControl() 
    {
       SetValue(ThisProperty, this);
    } 
    public IMyView This { get { return GetValue(ThisProperty); } set { /* do nothing */ } } 
}

finally in Xaml you can inject the view directly into the ViewModel using binding

<MyUserControl This="{Binding InjectedView, Mode=OneWayToSource}"/>

Try it out! I've used this pattern many times and you get an interface to the view injected once on startup. This means you maintain separation (Viewmodel can be tested as IView can be mocked), yet you get around the lack of binding support in many third party controls. Plus, its fast. Did you know binding uses reflection?

There's a demo project showcasing this pattern on the blog link above. I'd advocate trying out the Attached Property implementation of MiVVM if you are using a third party control.


You can have the list of viewmodels that you need to add controls for in an ObservableCollection in your main window viewmodel. You can then bind the ItemsSource of the RadGroupPanel to that collection and use the ItemTemplateSelector and ContentTemplateSelector of the RadGroupPanel to select the right template to use based on the viewmodel that is bound.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号