Это продолжение этого вопроса .В этом вопросе ОП попросил о возможности открыть ComboBox только в том случае, если пользователь нажимает кнопку ToggleButton.Если пользователь щелкает где-то еще, ничего не должно происходить.
Моя идея состояла бы в том, чтобы зарегистрироваться на событие PreviewMouseUp
, пройти по визуальному дереву исходного отправителя и установить свойство Handled
событияаргументы true
, если была найдена кнопка переключения.
Я ожидаю, что если я щелкну где-нибудь на кнопке переключения, экземпляр ToggleButton
будет найден в визуальном дереве, если я нажму за его пределами, экземпляр ToggleButton
не будет найден.
Я вижу, что экземпляр ToggleButton
обнаружен в обоих случаях.В визуализаторе WPF я нахожу только один ToggleButton
.Свойство OriginalSource
всегда является DockPanel
из ToggleButton
.У кого-нибудь есть объяснение этому?
XAML
<ComboBox PreviewMouseUp="UIElement_OnPreviewMouseUp">
<ComboBoxItem IsSelected="True">Item 1</ComboBoxItem>
<ComboBoxItem>Item 2</ComboBoxItem>
<ComboBoxItem>Item 3</ComboBoxItem>
</ComboBox>
Код позади
private void UIElement_OnPreviewMouseUp(object sender, MouseButtonEventArgs e)
{
var toggleButton = FindParent<ToggleButton>((DependencyObject)e.OriginalSource);
e.Handled = toggleButton != null;
}
public T FindParent<T>(DependencyObject child) where T : DependencyObject
{
var parentObject = VisualTreeHelper.GetParent(child);
switch (parentObject)
{
//we've reached the end of the tree
case null:
return null;
//check if the parent matches the type we're looking for
case T parent:
return parent;
//we move further to the root and keep looking
default:
return FindParent<T>(parentObject);
}
}