Проверка в обработчике события SelectionChanged
позволяет вам отменить логику, если выбор недействителен, но я не знаю простого способа отменить выбор события или элемента.
Мое решение состояло в том, чтобы создать подкласс поля со списком WPF и добавить внутренний обработчик для события SelectionChanged
. Всякий раз, когда происходит событие, мой личный внутренний обработчик вызывает вместо этого пользовательское событие SelectionChanging
.
Если свойство Cancel
установлено в соответствующем SelectionChangingEventArgs
, событие не возникает и SelectedIndex
возвращается к своему предыдущему значению. В противном случае возникает новый SelectionChanged
, который затеняет базовое событие. Надеюсь, это поможет!
EventArgs и делегат обработчика для события SelectionChanging:
public class SelectionChangingEventArgs : RoutedEventArgs
{
public bool Cancel { get; set; }
}
public delegate void
SelectionChangingEventHandler(Object sender, SelectionChangingEventArgs e);
Реализация класса ChangingComboBox:
public class ChangingComboBox : ComboBox
{
private int _index;
private int _lastIndex;
private bool _suppress;
public event SelectionChangingEventHandler SelectionChanging;
public new event SelectionChangedEventHandler SelectionChanged;
public ChangingComboBox()
{
_index = -1;
_lastIndex = 0;
_suppress = false;
base.SelectionChanged += InternalSelectionChanged;
}
private void InternalSelectionChanged(Object s, SelectionChangedEventArgs e)
{
var args = new SelectionChangingEventArgs();
OnSelectionChanging(args);
if(args.Cancel)
{
return;
}
OnSelectionChanged(e);
}
public new void OnSelectionChanged(SelectionChangedEventArgs e)
{
if (_suppress) return;
// The selection has changed, so _index must be updated
_index = SelectedIndex;
if (SelectionChanged != null)
{
SelectionChanged(this, e);
}
}
public void OnSelectionChanging(SelectionChangingEventArgs e)
{
if (_suppress) return;
// Recall the last SelectedIndex before raising SelectionChanging
_lastIndex = (_index >= 0) ? _index : SelectedIndex;
if(SelectionChanging == null) return;
// Invoke user event handler and revert to last
// selected index if user cancels the change
SelectionChanging(this, e);
if (e.Cancel)
{
_suppress = true;
SelectedIndex = _lastIndex;
_suppress = false;
}
}
}