Метод 1, приведенный ниже, показывает, возможно, ценную иллюстрацию метода, но большинство приложений, вероятно, лучше всего подойдет по Методу 2.
Метод 1
В качестве первого подхода я принял подход, предложенный jberger. Однако, поскольку я полагаюсь на значения, содержащиеся в аргументах события, и хочу сохранить разделение задач между моим View и ViewModel в соответствии с целями и принципами MVVM, я поместил эту добавленную логику в свой программный код, чтобы сохранить зависимость в Код вида.
Я использовал хэш содержимого AddedItems в аргументах событий, чтобы отличать «повторные» вызовы из-за привязки свойства другого ComboBox от новых вызовов метода обработки событий из-за взаимодействия с пользователем.
int hashCode = 0;
private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
string addedItemsCatString = "";
foreach (string item in e.AddedItems) addedItemsCatString += item;
int newHashCode = addedItemsCatString.GetHashCode();
if ( newHashCode == hashCode) return;
hashCode = newHashCode;
// execute Command code here
}
Конкатенация содержимого AddedItems не является строго необходимой для ComboBox, где одновременно может быть выбран только один элемент, но он допускает аналогичный подход для элементов управления с множественным выбором.
Метод 2
Поскольку я не был полностью удовлетворен методом 1, я продолжал думать о лучшем решении. Мне пришло в голову понимание, что я действительно хотел выполнить команду только один раз, основываясь на взаимодействии с пользователем. То, что похоже на хороший флаг, чтобы отличить событие SelectionChanged из-за взаимодействия с пользователем от события из-за привязки свойства, - это фокус клавиатуры.
private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (!(sender as FrameworkElement).IsKeyboardFocusWithin) return;
// execute Command code here
}
Таким образом, приведенный выше тест может быть лучшим решением для большинства случаев, в том числе для случаев, когда событие SelectionChanged инициируется другим режимом ввода, в котором не задействованы какие-либо селекторы GUI, например сочетанием клавиш или внутренним изменением состояние вашей программы - или в любом месте, где вы можете выполнить команду, что приведет к срабатыванию нескольких событий SelectionChanged, если вы использовали несколько элементов управления для управления настройкой. Свойство экземпляра FrameworkElement.IsKeyboardFocused и статический метод Keyboard.Focus (frameworkElementInstance) также могут быть полезны для различных элементов управления или сценариев.
Подробнее о фокусе клавиатуры можно узнать на MSDN здесь .