如何防止 ComboBox 的 SelectedIndex 更改?

How do I prevent the SelectedIndex of a ComboBox from changing?

提问人:Anton Schrage 提问时间:6/22/2023 最后编辑:Anton Schrage 更新时间:6/22/2023 访问量:62

问:

我正在寻找一个事件,在该事件中可以阻止设置 ComboBox 的 SelecteIndex 属性。 也许还有一个名为“SelectedIndexChanging”的自创事件。 我需要它来阻止 SelectedIndex 更改,直到特定条件为真。

我尝试寻找可以防止 SelectedIndex 更改的事件。 我还尝试在我的 CustomComboBox 中实现一个事件来阻止这种情况。 这里没有成功。

提前致谢。

编辑当用户更改 ComboBox 时,我将查看该对象是否保存在数据库中,如果没有,如果他想保存,是否会屏蔽他(使用 MessageBox)。有了那个 DialogResult,我想中断 SelectedIndex 的更改。

C# WinForms 事件 组合框 自定义控件

评论

1赞 jmcilhinney 6/22/2023
我认为禁用控件或从下拉列表中过滤除当前项目之外的所有项目都是要走的路。我不知道有什么方法可以防止选择的更改。如果您不希望更改选择并使用只读,甚至可能根本不显示,如果您反对禁用控件。ComboBoxTextBox
0赞 Anton Schrage 6/22/2023
我反对禁用 ComboBox,也无法使用 TextBox
1赞 Jimi 6/22/2023
您确实需要添加更多详细信息,以更好地定义此要求。避免在哪种情况下更改当前选择?当用户从界面中选择项目时?当绑定到数据源时,没有用户交互(仅处理货币管理器)?其他(例如,禁用在某些上下文中无法选择的项目 - >请参阅根据 CheckBox 状态禁用 ComboBox 项目< - 无需绘制禁用的项目)?
1赞 Matthew Watson 6/22/2023
为什么不直接设置,直到允许用户更改它,然后将其设置为?ComboBox.Enabled = false;true

答:

2赞 jmcilhinney 6/22/2023 #1

这有点黑客攻击,因为属性值实际上确实发生了变化,但如果事件被取消,属性值会再次更改回来,但从用户的角度来看,它肯定会起作用。如果你正在使用它们,你可能需要检查它们的行为方式。SelectedIndexSelectedIndexChangingSelectedValue

internal class ComboBoxEx : ComboBox
{
    private int previousSelectedIndex = -1;
    private bool isRevertingSelectedIndex = false;

    public event EventHandler<CancelEventArgs> SelectedIndexChanging;

    protected virtual void OnSelectedIndexChanging(CancelEventArgs e)
    {
        SelectedIndexChanging?.Invoke(this, e);
    }

    protected override void OnSelectedIndexChanged(EventArgs e)
    {
        if (isRevertingSelectedIndex)
        {
            isRevertingSelectedIndex = false;

            // Ignore the event altogether.
            return;
        }

        var cea = new CancelEventArgs();

        OnSelectedIndexChanging(cea);

        if (cea.Cancel)
        {
            // Revert the index to its previous value, so it appears not to have changed.
            isRevertingSelectedIndex = true;
            SelectedIndex = previousSelectedIndex;

            // Do not process the event any further.
            return;
        }

        // Commit the index change.
        previousSelectedIndex = SelectedIndex;

        base.OnSelectedIndexChanged(e);
    }
}

您只需处理事件并设置为“如果不应更改”。SelectedIndexChanginge.CanceltrueSelectedIndex

评论

1赞 Matthew Watson 6/22/2023
之后设置为 ,如何重置为?isRevertingSelectedindextruefalse
1赞 jmcilhinney 6/22/2023
@MatthewWatson,错过了。固定。
0赞 Anton Schrage 6/22/2023
我只是试图在更改索引之前停止它。我被困在自己的思绪中。谢谢你,伙计,我觉得它有点“脏”,但效果很好。
0赞 TonyMkenu 6/22/2023 #2

另一个小黑客...... 创建一个字段(元组),您可以在其中跟踪最后选择的索引以及是否可以更改它...

(bool blockChanges, int atIndex) comboRestriction = (false, 0);

在 SelectionChanged 方法中,添加以下内容:

ComboBox combo = (ComboBox)sender;

if (comboRestriction.blockChanges && combo.SelectedIndex != comboRestriction.atIndex)
{
     combo.SelectedIndex = comboRestriction.atIndex;
     return;
}
else if (comboRestriction.blockChanges)
{
      return;
 }

// Combo Changed - track last index
comboRestriction = (false, combo.SelectedIndex);
...

当您想要“阻止”comboBox时,请将其设置为“true”:

comboRestriction.blockChanges = true;