web-dev-qa-db-ja.com

C#でコンボボックス値の変更を防止/キャンセルするにはどうすればよいですか?

フォームの上部に、編集可能なデータを下のフィールドにロードするコンボボックスがあります。ユーザーが変更を加えたが保存されておらず、コンボボックスから別のオプションを選択しようとした場合、ユーザーに警告し、キャンセルまたは保存する機会を与えたいと思います。

キャンセル可能なイベント引数を持つ「BeforeValueChange」イベントが必要です。

達成する方法について何かアドバイスはありますか?

23
rg01

最初に入力した場合は、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;
    }
}
18
Denis Biondic

最も簡単な修正は次のとおりです。-

        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;
        }
5
Kushal Waikar

Enterイベントに現在の値を保存します。実際のBeforeValueChangeロジックの前に、ValueChangedイベントにValueChangedロジックを実装します。ユーザーがキャンセルした場合は、保存されている値を設定し、メソッド(return)を続行しないでください。

このシステムを頻繁に使用する場合は、ComboBoxを継承し、そこでBeforeValuechangeイベントを実装することをお勧めします。

このシナリオでは、検証イベントを使用できます
http://msdn.Microsoft.com/en-us/library/system.windows.forms.control.validating.aspx

2
Aleris

デフォルトでは、適切なイベントは発生しません。ユーザーがキャンセルしたい場合は、前の値をキャッシュして、その値に戻すことができます。

1
Daniel M

Validating/Validatedイベントを使用するのはどうですか?
ChangeではなくLostFocusで発生するイベントに問題がなければ、うまく機能します。

そうでなければ、どうですか

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

    // perform rest of onChange code
}
1
configurator

メッセージフィルター を使用して、クリックやキーの押下をインターセプトできます。これにより、コンボボックスの通常の動作を防ぐことができます。ただし、ユーザーが変更を加えたときにコンボボックスを無効にして、変更を保存するか元に戻すように要求する方がよいと思います。

0
Simon

実際に防ぐことはできませんが、特定の要件が満たされていない場合は、古い値に戻すことができます。

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
Tates