Я что-то не так делаю, когда открываю / закрываю окна? - PullRequest
0 голосов
/ 07 декабря 2018

Я заметил тревожное поведение в окнах, которые я открываю в своем приложении: команды и (что наиболее заметно) их методы «могут выполнять» запускаются долго после закрытия самого окна.

Вот сокращенный пример того, как я склонен что-то делать:

public class AllMaxThemedWindow : DevExpress.Xpf.Core.ThemedWindow, INotifyPropertyChanged
{
    public static DependencyProperty ShowMinimizeButtonProperty = DependencyProperty.Register("ShowMinimizeButton", typeof(Boolean), typeof(AllMaxThemedWindow), new PropertyMetadata(true));
    public Boolean ShowMinimizeButton
    {
        get => (Boolean)GetValue(ShowMinimizeButtonProperty);
        set => SetValue(ShowMinimizeButtonProperty, value);
    }
    //Maximize and Close DPs as well

    public AllMaxThemedWindow()
    {
        Loaded += AllMaxThemedWindow_Loaded;
    }

    private void AllMaxThemedWindow_Loaded(Object sender, RoutedEventArgs e)
    {
        if (!ShowMinimizeButton)
        {
            var button = (Button)DevExpress.Xpf.Core.Native.LayoutHelper.FindElementByName(this, DXWindow.ButtonParts.PART_Minimize.ToString());
            button.Visibility = Visibility.Collapsed;
        }

        //Maximize and Close checks as well

        //If neither maximize nor minimize is allowed, then prevent the system menu from being shown (via button or right-click).
        if (!ShowMaximizeButton && !ShowMinimizeButton)
        {
            var hwnd = new WindowInteropHelper(this).Handle;
            NativeMethods.SetWindowLong(hwnd, GWL_STYLE, NativeMethods.GetWindowLong(hwnd, GWL_STYLE) & ~WS_SYSMENU);
        }
    }
}

<atw:AllMaxThemedWindow x:Class="Antero.Windows.ThemedWindowInstance">
    <atw:AllMaxThemedWindow.DataContext>
        <vm:ThemedWindowInstanceViewModel />
    </atw:AllMaxThemedWindow.DataContext>
</atw:AllMaxThemedWindow>

//...opened this way in a view model's button command handler
new ThemedWindowInstance().ShowDialog(true);

Кроме этого, ничего особенного не происходит.В конечном итоге это просто Window, и это окно открывается как модальное.Затем пользователь нажимает X, чтобы закрыть его.

Вот тогда происходят плохие вещи.Например, в одном окне есть кнопка Save, и эта кнопка связана с командой (в ее модели представления), которая имеет метод «может быть выполнен».Этот метод будет запускаться еще долго после закрытия окна.На самом деле, кажется, что он работает вечно.

Я пришел из мира WinForms, поэтому я привык делать такие вещи, как Dispose, но, похоже, это не доступно для меня в WPF.Так что же в мире WPF заставляет окно (или его модель представления) навсегда зависать в подвешенном состоянии?

1 Ответ

0 голосов
/ 07 декабря 2018

Ваша реализация ICommand должна реализовывать событие CanExecuteChanged.И вы должны запускать это событие каждый раз, когда условие выполнения фактически изменяется.Обычно реализация ICommand имеет метод NotifyCanExecuteChanged.

public class DelegateCommand : ICommand
{
    private readonly Action<object> _execute = null;
    private readonly Predicate<object> _canExecute = null;

    #region Constructors

    public DelegateCommand(Action<object> execute)
        : this(execute, null) { }

    public DelegateCommand(Action<object> execute, Predicate<object> canExecute)
    {
        _execute = execute;
        _canExecute = canExecute;
    }

    #endregion

    #region ICommand Members

    public event EventHandler CanExecuteChanged;

    public bool CanExecute(object parameter)
    {
        return _canExecute != null ? _canExecute(parameter) : true;
    }

    public void Execute(object parameter)
    {
        if (_execute != null)
            _execute(parameter);
    }

    public void NotifyCanExecuteChanged()
    {
        if(CanExecuteChanged != null)
            CanExecuteChanged(this, EventArgs.Empty);
    }

    #endregion

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...