I'm using a combobox that gets it width from widest element described in Attached Behavior answer (currently 46 upvotes) in How can I make a WPF combo box have the width of its widest element in XAML?
public static void SetWidthFromItems(this ComboBox comboBox)
{
double comboBoxWidth = 19;// comboBox.DesiredSize.Width;
// Create the peer and provider to expand the comboBox in code behind.
ComboBoxAutomationPeer peer = new ComboBoxAutomationPeer(comboBox);
IExpandCollapseProvider provider = (IExpandCollapseProvider)peer.GetPattern(PatternInterface.ExpandCollapse);
EventHandler eventHandler = null;
eventHandler = new EventHandler(delegate
{
if (comboBox.IsDropDownOpen &&
comboBox.ItemContainerGenerator.Status == GeneratorStatus.ContainersGenerated)
{
double width = 0;
foreach (var item in comboBox.Items)
{
var container = comboBox.ItemContainerGenerator.ContainerFromItem(item);
if (container is ComboBoxItem)
{
var comboBoxItem = (ComboBoxItem) container;
comboBoxItem.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
if (comboBoxItem.DesiredSize.Width > width)
{
width = comboBoxItem.DesiredSize.Width;
}
}
else
{
/* FIXME: coming here means that for some reason ComboBoxItems */
/* are not generated even if comboBox.ItemContainerGenerator.Status seems to be OK */
return;
}
}
comboBox.Width = comboBoxWidth + width;
// Remove the event handler.
comboBox.ItemContainerGenerator.StatusChanged -= eventHandler;
comboBox.DropDownOpened -= eventHandler;
provider.Collapse();
}
});
comboBox.ItemContainerGenerator.StatusChanged += eventHandler;
comboBox.DropDownOpened += eventHandler;
// Expand the comboBox to generate all its ComboBoxItem's.
provider.Expand();
}
However the solution does not work when scaling text size on the fly in win10. The problem is that even though the condition
comboBox.ItemContainerGenerator.Status == GeneratorStatus.ContainersGenerated
is true, the call for
comboBox.ItemContainerGenerator.ContainerFromItem(item);
returns null from seemingly ok item.
So my question is: How should I alter the code that width is calculated correctly? I'm asking this because I don't have win10 and can't reproduce and play around. I gotta ask a colleague to test it.
I tried removing line
comboBox.ItemContainerGenerator.StatusChanged -= eventHandler;
this resulted in the correct width being measured when the narrow combobox was clicked with mouse. So one answer would be to force StatusChanged event to be raised somewhere somehow.