В событии ComboBox.SelectionChanged отправитель всегда ComboBox, и в SelectionChangedEventArgs нет ничего, что поможет вам.
Для меня это два решения. Вы можете использовать конвертер на привязке, или вы можете проверить трассировку стека, чтобы увидеть, находится ли в стеке System.Windows.Controls.Primitives.Selector.OnSelectedItemsCollectionChanged (объект, NotifyCollectionChangedArgs). Проверка стека крайне уродливая, плохая практика и не будет работать в среде с частичным доверием. Поэтому я опишу только один.
Использование нейтрализатора связывания для обнаружения источников изменения
Это решение является относительно чистым, но требует изменения связывания. Он также иногда уведомляет вас, когда все не изменилось.
Шаг 1: Создайте конвертер, который не делает преобразования, но имеет «преобразованное» событие и «ConvertedBack» событие:
public EventingConverter : IValueConverter
{
public event EventHandler Converted;
public event EventHandler ConvertedBack;
public object Convert(object value, ...)
{
if(Converted!=null) Converted(this, EventArgs.Empty);
return value;
}
public object ConvertBack(object value, ...)
{
if(ConvertedBack!=null) ConvertedBack(this, EventArgs.Empty);
return value;
}
}
Шаг 2: Установите ваши привязки использовать новый экземпляр этого преобразователя (не разделяют конвертер экземпляров с помощью словаря ресурсов или статическое свойство, как это обычно делается)
<ComboBox ...>
<ComboBox.SelectedValue>
<Binding Path="..." ...>
<Binding.Converter>
<local:EventingConverter
Converted="ComboBoxSelectedValue_Converted"
ConvertedBack="ComboBoxSelectedValue_ConvertedBack" />
</Binding.Converter>
</Binding>
</ComboBox.SelectedValue>
</ComboBox>
Теперь ваши методы ComboBoxSelectedValue_Converted и ComboBoxSelectedValue_ConvertedBack будут вызываться внутри процесса связывания.
Предупреждение. Если вы сделаете исключение в этих событиях, вы нарушите привязку.
Если вы не можете изменить XAML, что делает привязку
Если вы не имеете никакого контроля над XAML, который создает привязку (например, вы используете вложенные свойства) вы можете прийти и добавить конвертер после факта. В этом случае вашему классу конвертера необходимо будет привязать к ранее объявленному конвертеру, вам придется клонировать привязку и устанавливать новую (они неизменяемы после их использования), и вам также придется иметь дело с MultiBindings (если вы хотите их поддержать).
Конечная нота
необходимость определить, было ли сделано изменение пользователем или свойство на самом деле может быть симптомом плохого дизайна пользовательского интерфейса, как правило, в результате чего от пользователей, которые на самом деле не понимают их собственные требования.
У меня было несколько проектов, над которыми я работал, когда конечный пользователь указал, что такое-то и должно было произойти «когда я меняю этот ComboBox».Практически в каждом случае оказалось, что приложение будет вести себя неожиданно в некоторых случаях использования, и мы нашли лучший способ достичь цели. Во многих случаях то, что действительно хотел пользователь, было «когда это значение сначала отличается от значения в базе данных» или «когда это значение больше не является значением по умолчанию» или «когда это значение равно 5».
Комментарий к парню, который был только что удален его ответ: Вы, наверное, догадались, что отправитель * всегда * выпадающий, но я думал, что вы хотели бы знать ваше тело метод может быть упрощено, если (отправитель это ComboBox), тогда {blah} else {blah} –