Member 12606650 Ответов: 2

Создайте универсальную кнопку closewindow в MVVM


В настоящее время я портирую графический интерфейс из Unix X11 XWindows в WPF/MVVM. Этот графический интерфейс имеет главное окно, из которого можно открыть множество других подокон. Эти подокна имеют стандартный набор кнопок ("->Main", который выводит главное окно на передний план, "Print", "Events", который покажет все события, связанные с этим подокном,...). Одна из этих кнопок - "закрыть", которая просто закроет это окно.

Есть ли способ создать кнопку, которая сопоставляется с кнопкой Windows "x", которую я мог бы настроить как ресурс один раз, а затем просто привязать к ней?

Или есть общий способ создать кнопку без необходимости обновлять код каждого окна позади нее.

Я использую Foddy Weaver и Ninject. Кроме того, существует модель главного представления, с которой сопоставляется большинство подокон (поскольку во многих подокнах отображается общая информация о состоянии), если это помогает (или усложняет!).

Что я уже пробовал:

Попробовал этот метод : Закрытие окна WPF с использованием MVVM и минимального кода- jkshay.com[^] но он не компилировался (возможно, это противоречит тому, как я сейчас делаю RelayCommands в примерах Angel6)

Никогда не мог заставить "GetTemplateChild", ища PART_CloseWindow (и некоторые другие имена, сейчас не помню) работать.

Многие примеры команд ретрансляции привязаны к одной переменной, но это не работает для одной модели представления, разделяемой между несколькими подокнами (закрыло бы их все)

2 Ответов

Рейтинг:
9

Member 12606650

Я понял это сам, и вот что я сделал:

Я создал интерфейс, называемый ICloseable, который будет использоваться в коде позади:

namespace MyProgram.Interfaces
{
    public interface ICloseable
    {
        void Close();
    }
}

В моем ApplicationViewModel.cs я добавляю команду для закрытия окна:
  ...
public ICommand CloseWindow_Command { get; private set; }
  ...
public ApplicationViewModel()
{
      ...
    CloseWindow_Command = new RelayCommand<ICloseable>(CloseWindow);
      ...
}
  ...
public void CloseWindow(ICloseable window)
{
    if (window != null)
    {
        window.Close();
    }
}
  ...

В данном окне я добавляю имя окна в главное объявление (уникальное значение для каждого окна) и добавляю это имя в качестве параметра CommandParameter в кнопку Close (которая вызывает команду close):
<Window x:Class="MyProgram.Window1"
        x:Name="theWindow1"
        ... >

            ...
        <Button Height="16" Width="45" 
                Content="Close" FontSize="9"                           
                Command="{Binding AppVM.CloseWindow_Command}"
                CommandParameter="{Binding ElementName=theWindow1}"
                ToolTip="Close this window"/>
            ...

А вот и код-зад для данного окна, добавляющий интерфейс ICloseable:
namespace MyProgram
{
    public partial class Window1 : Window, ICloseable
    {
        public Window1()
        {
            public ApplicationViewModel AppVM = ApplicationViewModel.Instance;
            InitializeComponent();
        }
    }
}


Рейтинг:
1

#realJSOP

Вы можете создать базовый класс окна с соответствующим обработчиком событий в нем и вывести все ваши фактические окна из этого базового класса. В этот момент вы можете добавить Click обработчик событий в XAML и просто укажите его на метод обработчика базового класса.

Если вы хотите сделать возможным переопределение обработчика в определенных окнах, просто создайте обработчик в базовом классе virtual.