Priya Karthish Ответов: 1

Привязка кнопки для закрытия окна не работает


Я попробовал привязку кнопок для закрытия окна с интерфейсом.Но я не мог понять, почему моя привязка не срабатывает. Пожалуйста помочь....

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

public interface IClosable
    {
        void Close();
    }

In my ViewModel :-
public DelegateCommand<IClosable> CloseCommand { get; private set; } 

public MainViewModel()
{
CloseCommand = new DelegateCommand<IClosable>(CloseWindow, CanCloseWindow);
}
private bool CanCloseWindow(IClosable parameter)
        {
            return true;
        }
        private void CloseWindow(IClosable parameter)
        {
            var closable = parameter as IClosable;
            if (closable != null)
            {
                closable.Close();
            }
        }


На мой взгляд(XAML):-
Мое окно называется Рествиндо
<Button x:Name="btnExit" Height="30" Width="30" Content="Exit" Command="{Binding CloseCommand, Mode=OneWay}" CommandParameter="{Binding ElementName=RestWindow}" Margin="450,125,9.8,0.2"/>

свойство DataContext:-
MainViewModel data = new MainViewModel();
btnExit.DataContext = data;

George Swan

Вам нужно указать в определении класса вашего окна, что окно реализует ICloseable. Недостаточно полагаться на то, что в вашем окне есть метод с именем Close. Я бы поместил методы, расширяющие функциональность окна, в код окна позади, а не в viewmodel. Кроме того, нет необходимости устанавливать контекст данных элементов управления по отдельности. Просто установите контекст данных окна, и элементы управления окна " унаследуют’ его.

Priya Karthish

Я уже реализовал интерфейс ICloseable в определении класса моего окна.
Кроме того, extednign код для метода Close в Window(VIew) вместо ViewModel не является правильным вариантом в MVVM(это моя мысль). Любые другие предложения, пожалуйста...

johannesnestler

Нет, Джордж Свон прав, он не тормозит MVVM, потому что это технология только для просмотра (чтобы вызвать конкретный метод закрытия). Я архитектор большой системы, и мы тоже используем MVVM, решили проблему, как описал Джордж Свон. "Трюк" заключается в том, чтобы реализовать его через OnDataContextChanged следующим образом:
OnDataContextChanged недействительным(объект отправителя, DependencyPropertyChangedEventArgs е)
{
если (электронная.NewValue является IRequestClose)
{
((IRequestClose)e.NewValue).RequestClose += (s, ea) =>
{
Диспетчер.Invoke(() =>
{
если (это.свойство IsVisible)
{
этот.DialogResult = ((IRequestClose)e.NewValue).свойство DialogResult;
}
этот.Закрывать();
});
};
}
}

Итак, вы видите: мы ищем DataContexts (ViewModels) для реализации IRequestClose и прикрепляем к нему событие RequestClose. Таким образом, мы можем "вызвать" закрытие отовсюду, и представление знает о своем viewmodel, но viewmodels не знает, что это view (и ist Technology independend!) - Так что MMVM pure сохраняется относительно этого…


Не стесняйтесь спрашивать подробности.

Priya Karthish

Спасибо за ясное объяснение.

1 Ответов

Рейтинг:
2

Graeme_Grant

Вот более простой способ обработки окна Closing событие, которое позволяет отменить событие, если это необходимо. ie: если есть ожидающие изменения данных, например:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        Closing += OnClosing;
        InitializeComponent();
    }

    private void OnClosing(object sender, CancelEventArgs e)
        => e.Cancel = ((IRequestClose)DataContext).IsCancelled();
}

public interface IRequestClose
{
    bool IsCancelled();
}

Затем примените интерфейс к ViewModel и реализуйте метод.


Priya Karthish

извините за задержку. Спасибо за все ваши ответы. Каким-то образом я нашел решение этой проблемы.