How to transfer a WPF window using MVVM?

This is probably too large in the MVVM pattern, but it is new to me, and I am interested to know if this is possible.

If I join the MouseMove event for a window and make DragMove, I can move the boundless window. Can I achieve this using some other method in MVVM or should I just add this code to Windowbox code?

+3
source share
5 answers

This is pure interface logic and is not part of the ViewModel. The only reason you don't want to embed this in your code is reuse, and this is best solved with the custom Window control.

+3
source

, , MVVM, . , , .

+3

, , ( ), "", .

+2

, , , - , .

DashboardViewModel viewModel;
public DashboardView()
{
    InitializeComponent();
    viewModel = new DashboardViewModel();
    viewModel.RequestClose += (s, e) => Application.Current.Dispatcher.Invoke(this.Close);
    viewModel.RequestMinimize += (s, e) => Application.Current.Dispatcher.Invoke(() => { this.WindowState = WindowState.Minimized; });
    DataContext = viewModel;
}

- Model

#region Public Event Handlers
public event EventHandler<EventArgs> RequestClose;
public event EventHandler<EventArgs> RequestMinimize;
#endregion

ICommand...

#region ICommand Members
public ICommand CloseCommand { get; private set; }
public ICommand MinimizeCommand { get; private set; }
#endregion

...

private void SetupCommands()
{
    CloseCommand = new RelayCommand(CloseApplication);
    MinimizeCommand = new RelayCommand(MinimizeApplication);
}

RelayCommand.

public class RelayCommand : ICommand
{
#region Private Readonly Properties
private readonly Action<object> executeCommand;
private readonly Predicate<object> canExecute;
#endregion

#region Constructors
public RelayCommand(Action<object> execute) : this(execute, null)
{

}
public RelayCommand(Action<object> execute, Predicate<object> canExecute)
{
    if (execute == null) 
        throw new ArgumentNullException("execute");
    this.executeCommand = execute; 
    this.canExecute = canExecute;
}
#endregion

#region Public ICommand Members
public bool CanExecute(object parameter)
{
    return canExecute == null ? true : canExecute(parameter);
}
public event EventHandler CanExecuteChanged
{
    add { CommandManager.RequerySuggested += value; }
    remove { CommandManager.RequerySuggested -= value; }
}
public void Execute(object parameter)
{
    executeCommand(parameter);
}
#endregion
}

...

private void MinimizeApplication(object obj)
{
    RequestMinimize(this, new EventArgs());
}
private void CloseApplication(object obj)
{
    RequestClose(this, new EventArgs());
}

, !

+2

. - . Cinch, . DragMove, ( , , , ).

XAML:

<Window 
    xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
    xmlns:cinchV2="clr-namespace:Cinch;assembly=Cinch.WPF"
    ...>
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="MouseLeftButtonDown">
            <cinchV2:EventToCommandTrigger Command="{Binding MouseLeftButtonDown}" />
        </i:EventTrigger>
    </i:Interaction.Triggers>
    <Grid>
        ...
    </Grid>
</Window>

ViewModel:

[ExportViewModel("MainViewModel")]
[PartCreationPolicy(CreationPolicy.NonShared)]
internal sealed class MainViewModel : ViewModelBase
{
    public SimpleCommand<object, EventToCommandArgs> MouseLeftButtonDown { get; private set; }

    [ImportingConstructor]
    public MainViewModel(IUIVisualizerService uiVisualizerService)
    {
        ...
        MouseLeftButtonDown = new SimpleCommand<object, EventToCommandArgs>(OnMouseLeftButtonDown);
    }

    private static void OnMouseLeftButtonDown(EventToCommandArgs e)
    {
        ((Window)e.Sender).DragMove();
    }
}

Pretty simple, right? Any events that come from the user interface contain a view as the sender. So, here we just call the method in the view inside the event handler in the ViewModel.

The project I'm working on does not use code (even if it is not recommended in MVVM).

+1
source

Source: https://habr.com/ru/post/1758426/


All Articles