0
votes

I would like to Minimize my application by clicking on a UserControl button using MVVM.

Here is my ViewModel class:

public class HeaderViewModel : ViewModelBase, IHeaderViewModel
{
    public DelegateCommand MinimizeWindowCommand { get; set; }
    public HeaderViewModel(IHeaderView view) : base(view)
    {
        MinimizeWindowCommand = new DelegateCommand(OnMinimizeWindow);
    }
    private void OnMinimizeWindow()
    {
        /*
         * This is where I would like to minimize my Application
         * Something like MainWindow
         */
    }
}

When I click on my UserControl button, the MinimizeWindowCommand is called. In the OnMinimize() method, I wish to set the MainWindow visibility to Hidden.

By the way, I am using Prism and the UserControl is directly injected in the MainWindow as follow :

<Window
    xmlns:prism="http://prismlibrary.com/"
    [...]
    Title="Shell"
    x:Name="Shell">
    <ScrollViewer>
        <StackPanel>
            <ContentControl prism:RegionManager.RegionName="{x:Static infra:RegionNames.HeaderRegion}" />
        </StackPanel>
    </ScrollViewer>
</Window>

Thank you ! Chcoum

1
"Minimize my application by clicking on a UserControl button" - I don't see a reason to involve view model in that operationASh
Don't do this inside a view model. View model has absolutely no UI context. This is how it is intended to be, if you want to follow the pattern correctly. The view model is focused on data only and therefore only has access to the model. The window should handle this itself. You can use a Routed command or RoutedEvent, where either is handled by the Window. To hide something (manipulate the visual tree), you usually use triggers like Data trigger or EventTrigger. UI logic belongs to the UI, always.BionicCode
Hi guys, thank you for your quick replies but there is something I don't understand then. If I bind the Visibility property of a Window or UserControl in the appropriate ViewModel, I thought that I was still following the MVVM pattern correctly, am I?Chcoum
@Chcoum: When you say "minimize my application" I guess you mean minimize the window that HeaderViewModel is the DataContext of, right? Or what's the relationship between the view model and the window that you are trying to minimize?mm8
@mm8: yes, I was trying to minimize my application MainWindow that contains a UserControl. And the button responsible for this, is in my UserControl. I found a solution that works with Prism. See my answer below. :) Thanks anywayChcoum

1 Answers

0
votes

I found a solution and I took into account the comments.

With Prism Framework, you can use IEventAggregator to send messages between different part of your application. Here are the different steps with Prism.

Create a class that contains the reference of your event.

In that file, create a reference of your event as a class.

namespace MyNameSpace
{
    public class ViewUpdatedEvent : PubSubEvent<bool> { }
}

Publish this event in the ViewModel:

public class HeaderViewModel
{
    private IEventAggregator _eventAggregator;

    public DelegateCommand MinimizeWindowCommand { get; set; }

    public HeaderViewModel(IHeaderView view,IEventAggregator eventAggregator) : base(view)
    {
        _eventAggregator = eventAggregator;
        MinimizeWindowCommand = new DelegateCommand(OnMinimizeWindow);
    }

    private void OnMinimizeWindow()
    {
        _eventAggregator.GetEvent<ViewUpdatedEvent>().Publish(true);
    }
}

I send the parameter "true" to say that I want to reduce my Window.

Subscribe this event in the code-behind of the View:

public partial class Shell : Window
{
    public Shell(IEventAggregator eventAggregator)
    {
        InitializeComponent();
        eventAggregator.GetEvent<ViewUpdatedEvent>().Subscribe(OnMinimizeApp);
    }

    private void OnMinimizeApp(bool parameter)
    {
        if (parameter)
            this.Visibility = Visibility.Hidden;
    }
}

That's it. I'm falling in love with Prism ^^. Hope this help.