Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting Window from view model

Tags:

c#

mvvm

wpf

I have created a custom messageBox Window to replace the typical MessageBox.

My custom messageBox (child Window) needs parent window to be passed as an argument. The parent window is where child window will be located within in the location specified (Top Left, Top Center, etc.) also as an argument.

So when calling my custom messageBox from view model, I need to get the Window to pass it through. How can I get the Window associated to the view model?

Maybe using an Interface like commented here? I am trying to implement it but this.DataContext.View does not exist.

I am using Visual Studio 2008.

ATTEMPT #1: mm8 solution

<Window x:Class="MyNamespace.Main"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:viewmodel="clr-namespace:MyNamespace.ViewModels">
    <Window.Resources>
        <viewmodel:MainViewModel x:Key="wMainViewModel" />
    </Window.Resources>

    <Grid DataContext="{StaticResource wMainViewModel}">
    </Grid>
</Window>

Taken into account that I initialize DataContext from xaml and not in code-behind from constructor, how can I pass the view to the view model¿?

like image 814
Ralph Avatar asked Jan 03 '23 05:01

Ralph


1 Answers

How can I get the Window associated to the view model?

You could inject the view model with an interface that the window implements:

public interface IView
{
    double Top { get; }
    double Left { get; }
    double Height { get; }
    double Width { get; }
}

public partial class MainWindow : Window, IView
{
    public MainWindow()
    {
        InitializeComponent();
        DataContext = new ViewModel(this);
    }
}

public class ViewModel
{
    private readonly IView _view;

    public ViewModel(IView view)
    {
        _view = view;
    }

    //...
}

Then the view model knows only about an interface (which maybe should be called something else than IView).

If you want an ugly and non-MVVM friendly shortcut, you could use the Application class:

var win = Application.Current.MainWindow;

A factory class to create everything:

public MainWindow WindowFactory()
{
    MainWindow mainWindow = new MainWindow();
    ViewModel viewModel = new ViewModel();
    mainWindow.DataContext = viewModel;

    return mainWindow;
}
like image 155
mm8 Avatar answered Jan 10 '23 11:01

mm8