如何在C#中防止/取消组合框的值更改?

25

我在表单顶部有一个下拉框,用于加载下方可编辑的数据。如果用户更改了数据但没有保存,并尝试从下拉框中选择其他选项,我想要提醒他们并给予取消或保存的机会。

我需要一个“BeforeValueChange”事件,其中包含可取消的事件参数。

如何实现?有什么建议吗?

8个回答

19

在ComboBox第一次输入时,保存其SelectedIndex,然后在需要取消更改时恢复其值。

cbx_Example.Enter += cbx_Example_Enter;
cbx_Example.SelectionChangeCommitted += cbx_Example_SelectionChangeCommitted;

...

private int prevExampleIndex = 0;
private void cbx_Example_Enter(object sender, EventArgs e)
{
    prevExampleIndex = cbx_Example.SelectedIndex;
}

private void cbx_Example_SelectionChangeCommitted(object sender, EventArgs e)
{
    // some custom flag to determine Edit mode
    if (mode == FormModes.EDIT) 
    {
        cbx_Example.SelectedIndex = prevExampleIndex;
    }
}

1
这是一个完美的解决方案,可以替代SelectionChanging事件。谢谢!-- Matthew - Matthew M.
2
使用“Enter”事件来保存最后的选择并不是必要的。只需在退出“SelectionChangeCommitted”事件处理程序之前,将lastSelectedIndex值保存为private变量即可。此后,进入该事件处理程序的后续条目可以使用lastSelectedIndexComboBox.SelectedIndex设置为先前的位置。 - Jim Fell

8
这里是最简单的解决方案:-
        bool isSelectionHandled = true;

        void CmbBx_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (isSelectionHandled)
            {
                MessageBoxResult result = MessageBox.Show("Do you wish to continue selection change?", this.Title, MessageBoxButton.YesNo, MessageBoxImage.Question);
                if (result == MessageBoxResult.No)
                {
                    ComboBox combo = (ComboBox)sender;
                    isSelectionHandled = false;
                    if (e.RemovedItems.Count > 0)
                        combo.SelectedItem = e.RemovedItems[0];
                    return;
                }
            }
            isSelectionHandled = true;
        }

这个事件 SelectionChanged 是什么?是来自于 WinForm ComboBox 吗? - i486
@i486 是的,没错。 - raulmd13

4

Enter事件中保存当前值。

在实际的ValueChanged逻辑之前,在ValueChanged事件中实现BeforeValueChange逻辑。如果用户取消操作,则设置存储的值并不要在该方法继续执行(return)。

如果您需要经常使用此系统,建议继承ComboBox并在其中实现您的BeforeValuechange事件。


2

3
这是在你失去焦点之后发生的,因此无法起作用。我需要一个在用户尝试更改值“之前”发生的事件。 - rg01
@RG - 你不能将焦点重新设置到组合框吗?还是它失去焦点时发生了某些处理? - Lucas Jones

1

默认情况下,您无法获得适当的事件。如果用户想要取消,您可以缓存先前的值并将其设置回去。


1

使用验证/已验证事件怎么样?
如果在失去焦点而不是更改时发生事件对你没问题,那么它可以很好地工作。

否则,还有哪些选择呢?

public void Combobox_ValueChanged(object sender, EventArgs e) {
    if (!AskUserIfHeIsSureHeWantsToChangeTheValue())
    {
        // Set previous value
        return;
    }

    // perform rest of onChange code
}

1

你无法真正地阻止它,但是如果满足某些要求,你可以将其更改回旧值:

private SomeObject = selectedSomeObject=null;

private void cbxTemplates_SelectionChangeCommitted(object sender, EventArgs e)
{
  if (!(sender is ComboBox cb)) return;
  if (!(cb.SelectedItem is SomeObject tem)) return;
  if (MessageBox.Show("You sure?", "??.",
        MessageBoxButtons.OKCancel) != DialogResult.OK)
    cb.SelectedItem = selectedSomeObject;
  else
  {
    selectedSomeObject = tem;
  }
}

0

您可以使用消息过滤器来拦截点击和按键,从而防止组合框的正常行为。但我认为当用户进行更改时最好禁用组合框,并要求他们保存或撤消更改。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接