I need to find the ComboBox that a ComboBoxItem resides in.
In codebehind I catch an event when a ComboBoxItem is clicked, but I don't know which one of several ComboBoxes that the specific ComboBoxItem belongs to. How do I find the ComboBox?
Normally you can use LogicalTreeHelper.GetParent() and traverse up the logical tree from the ComboBoxItem to find the ComboBox. But this only works if the ComboBoxItems are added to the ComboBox manually, not when the items are applied to the ComboBox with databinding. When using databinding, the ComboBoxItems do not have the ComboBox as a logical parent (I don't understand why).
Any ideas?
More info:
Below is some code reconstructing my problem (not my actual code). If I would change from databinding the ComboBoxItems to setting them manually (in the XAML), the variable "comboBox" would be set to the correct ComboBox. Now comboBox is only null.
XAML:
<ComboBox Name="MyComboBox" ItemsSource="{Binding Path=ComboBoxItems, Mode=OneTime}" />
CodeBehind:
public MainWindow()
{
InitializeComponent();
MyComboBox.DataContext = this;
this.PreviewMouseDown += MainWindow_MouseDown;
}
public BindingList<string> ComboBoxItems
{
get
{
BindingList<string> items = new BindingList<string>();
items.Add("Item E");
items.Add("Item F");
items.Add("Item G");
items.Add("Item H");
return items;
}
}
private void MainWindow_MouseDown(object sender, MouseButtonEventArgs e)
{
DependencyObject clickedObject = e.OriginalSource as DependencyObject;
ComboBoxItem comboBoxItem = FindVisualParent<ComboBoxItem>(clickedObject);
if (comboBoxItem != null)
{
ComboBox comboBox = FindLogicalParent<ComboBox>(comboBoxItem);
}
}
//Tries to find visual parent of the specified type.
private static T FindVisualParent<T>(DependencyObject childElement) where T : DependencyObject
{
DependencyObject parent = VisualTreeHelper.GetParent(childElement);
T parentAsT = parent as T;
if (parent == null)
{
return null;
}
else if (parentAsT != null)
{
return parentAsT;
}
return FindVisualParent<T>(parent);
}
//Tries to find logical parent of the specified type.
private static T FindLogicalParent<T>(DependencyObject childElement) where T : DependencyObject
{
DependencyObject parent = LogicalTreeHelper.GetParent(childElement);
T parentAsT = parent as T;
if (parent == null)
{
return null;
}
else if(parentAsT != null)
{
return parentAsT;
}
return FindLogicalParent<T>(parent);
}
This is probably what you are looking for:
var comboBox = ItemsControl.ItemsControlFromItemContainer(comboBoxItem) as ComboBox;
I love how descriptive that method-name is.
On a side-note, there are some other useful methods which can be found in the property ItemsControl.ItemContainerGenerator
which let you get the container associated with the templated data and vice versa.
On another side-note, you usually should not be using any of them and instead use data-binding actually.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With