阻止用户控件关闭WPF C#

时间:2016-07-06 10:21:35

标签: c# wpf user-controls

我有一个用户填写表单的应用程序,如果用户没有按下保存并加载另一个控件/按钮,我需要停止用户离开并销毁用户控件。用户控件上没有Closing事件。我尝试过卸载,但这已经与可视树断开了。 我是否必须在整个过程中创建变量才能检查? 是否有用于此情况的事件?

更新

所以我有一个应用程序窗口,许多用户控件加载到网格中,例如,如果客户端按联系人,则新的联系人用户控件将作为窗口的子项出现。如果用户没有按下保存,我希望不删除用户控件并提示消息。希望能解释一下。

3 个答案:

答案 0 :(得分:1)

因此,据我了解您的问题,您可以在主窗口的代码中交换用户控件。如果输入不完整,您不希望交换其中一个控件。

你必须自己编码。您可能在主窗口的代码中有一个类似以下的方法切换到另一个UserControl

private void SwapView(UserControl newView)
{
    // Remove old user control
    ...

    // Show new user control
    ...
}

您需要的是UserControl派生类中的一些标志,指示是否可以交换。最好,你定义一个这样的界面:

public interface IView
{
    bool CanClose();
}

所有 UserControl实现它:

public class MyControl : UserControl, IView
{
    ...

    public bool CanClose()
    {
        // Determine whether control can be closed
        bool result = ...
        return result;
    }

    ...
}

然后您可以将上述方法更改为:

private void SwapView(IView newView)
{
    // Get current view
    IView currentView = ...

    // Check whether it can be closed
    if (!currentView.CanClose())
    {
        ...
        return;
    }

    // Remove old user control
    ...

    // Show new user control
    ...
}

您可以轻松扩展此功能,以便向用户显示一条消息,提供无法更改视图的原因。

答案 1 :(得分:0)

最简单且可能最优雅的解决方案是使用此附加属性

public static class WindowEventHelpers
    {
        #region Static Fields

        /// <summary>
        /// Attached property to define the command to run when the windows is closing
        /// </summary>
        public static readonly DependencyProperty WindowClosingCommandProperty = DependencyProperty.RegisterAttached(
            "WindowClosingCommand",
            typeof(ICommand),
            typeof(WindowEventHelpers),
            new PropertyMetadata(null, OnWindowClosingCommandChanged));


        #endregion

        #region Public Methods and Operators

        /// <summary>
        /// Returns the WindowClosingCommand dependency property value.
        /// </summary>
        /// <param name="target">
        /// The <see cref="DependencyProperty"/> identifier.
        /// </param>
        /// <returns>
        /// The WindowClosingCommand dependency property value.
        /// </returns>
        public static ICommand GetWindowClosingCommand(DependencyObject target)
        {
            return (ICommand)target.GetValue(WindowClosingCommandProperty);
        }

        /// <summary>
        /// Set the WindowClosingCommand dependency property value
        /// </summary>
        /// <param name="target">
        /// The <see cref="DependencyProperty"/> identifier.
        /// </param>
        /// <param name="value">
        /// The dependency property value.
        /// </param>
        public static void SetWindowClosingCommand(DependencyObject target, ICommand value)
        {
            target.SetValue(WindowClosingCommandProperty, value);
        }

        /// <summary>
        /// Returns the WindowClosingCommand dependency property value.
        /// </summary>
        /// <param name="target">
        /// The <see cref="DependencyProperty"/> identifier.
        /// </param>
        /// <returns>
        /// The WindowClosingCommand dependency property value.
        /// </returns>
        public static ICommand GetWindowContentRenderedCommand(DependencyObject target)
        {
            return (ICommand)target.GetValue(WindowContentRenderedCommandProperty);
        }

        #endregion

        #region Methods

        private static void ClosingEventHandler(object sender, CancelEventArgs e)
        {
            var control = (Window)sender;
            var command = (ICommand)control.GetValue(WindowClosingCommandProperty);
            command.Execute(e);
        }


        private static void OnWindowClosingCommandChanged(DependencyObject target, DependencyPropertyChangedEventArgs e)
        {
            var command = (ICommand)e.NewValue;

            if (target is Window)
            {
                // var fe = (FrameworkElement)target;
                var control = (Window)target;

                //check if we need to add the event handler or we need to remove it
                if ((command != null) && (e.OldValue == null))
                {
                    control.Closing += ClosingEventHandler;
                }
                else if ((command == null) && (e.OldValue != null))
                {
                    control.Closing += ClosingEventHandler;
                }
            }
        }


        #endregion
    }

在XAML中,您需要绑定

ap:WindowEventHelpers.WindowClosingCommand =&#34; {Binding CheckBeforeClosing}&#34;

最后在后面的代码或ViewModel中,您需要定义并启动一个新命令:

public ICommand CheckBeforeClosing
{
  get;
  private set;
}

this.CheckBeforeClosing = new Command<CancelEventArgs>(this.CheckBeforeClosingMethod);

private void CheckBeforeClosingMethod(CancelEventArgs EventArgs)
{
      //Cancel the closing TODO Add the check
      EventArgs.Cancel = true;       
}

答案 2 :(得分:-1)

您可以覆盖OnClosing事件。

    protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
    {
        base.OnClosing(e);
    }