views:

34

answers:

2

Hello guys. I've got combobox binded to string[]. I haven't got clear combobox items. But I want measure my dropown items. How can I get width of items in combobox at runtime. I need this to manage width of my combo.

A: 
foreach(var item in MyComboBox.Items){

    double width = item.ActualWidth;

}
gmcalab
item is string, it hasn't ActualWidth property
Andrew Kalashnikov
+3  A: 

If you want to do this and you're not sure if all your ComboBoxItems have been generated then you can use this code. It will expand the ComboBox in code behind and when all the ComboBoxItems within it are loaded, measure their size, and then close the ComboBox.

The IExpandCollapseProvider is in UIAutomationProvider

public void SetComboBoxWidthFromItems()
{
    double comboBoxWidth = c_comboBox.DesiredSize.Width;

    // Create the peer and provider to expand the c_comboBox in code behind.
    ComboBoxAutomationPeer peer = new ComboBoxAutomationPeer(c_comboBox);
    IExpandCollapseProvider provider = (IExpandCollapseProvider)peer.GetPattern(PatternInterface.ExpandCollapse);
    EventHandler eventHandler = null;
    eventHandler = new EventHandler(delegate
    {
        if (c_comboBox.IsDropDownOpen &&
            c_comboBox.ItemContainerGenerator.Status == GeneratorStatus.ContainersGenerated)
        {
            double width = 0;
            foreach (var item in c_comboBox.Items)
            {
                ComboBoxItem comboBoxItem = c_comboBox.ItemContainerGenerator.ContainerFromItem(item) as ComboBoxItem;
                comboBoxItem.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
                if (comboBoxItem.DesiredSize.Width > width)
                {
                    width = comboBoxItem.DesiredSize.Width;
                }
            }
            c_comboBox.Width = comboBoxWidth + width;
            // Remove the event handler.
            c_comboBox.ItemContainerGenerator.StatusChanged -= eventHandler;
            c_comboBox.DropDownOpened -= eventHandler;
            provider.Collapse();
        }
    });
    // Anonymous delegate as event handler for ItemContainerGenerator.StatusChanged.
    c_comboBox.ItemContainerGenerator.StatusChanged += eventHandler;
    c_comboBox.DropDownOpened += eventHandler;
    // Expand the c_comboBox to generate all its ComboBoxItem's.
    provider.Expand();
}

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    SetComboBoxWidthFromItems();
}
Meleak
Perfect. Where dou know about this trick? I try it for two days
Andrew Kalashnikov
Yes, took me a while too. I kind of puzzled it together piece by piece. The ItemContainerGenerator.StatusChanged is very common but in this case, it wasn't enough for about 1% of the cases so I had to add DropDownOpened event as well. The way to expand and collapsed was found through google :-)
Meleak