How can I make a WPF combo box have the width of its widest element in XAML?

前端 未结 13 2143
清酒与你
清酒与你 2020-11-30 18:58

I know how to do it in code, but can this be done in XAML ?

Window1.xaml:



        
13条回答
  •  难免孤独
    2020-11-30 19:35

    A follow up to Maleak's answer: I liked that implementation so much, I wrote an actual Behavior for it. Obviously you'll need the Blend SDK so you can reference System.Windows.Interactivity.

    XAML:

        
            
                
            
        
    

    Code:

    using System;
    using System.Windows;
    using System.Windows.Automation.Peers;
    using System.Windows.Automation.Provider;
    using System.Windows.Controls;
    using System.Windows.Controls.Primitives;
    using System.Windows.Interactivity;
    
    namespace MyLibrary
    {
        public class ComboBoxWidthBehavior : Behavior
        {
            protected override void OnAttached()
            {
                base.OnAttached();
                AssociatedObject.Loaded += OnLoaded;
            }
    
            protected override void OnDetaching()
            {
                base.OnDetaching();
                AssociatedObject.Loaded -= OnLoaded;
            }
    
            private void OnLoaded(object sender, RoutedEventArgs e)
            {
                var desiredWidth = AssociatedObject.DesiredSize.Width;
    
                // Create the peer and provider to expand the comboBox in code behind. 
                var peer = new ComboBoxAutomationPeer(AssociatedObject);
                var provider = peer.GetPattern(PatternInterface.ExpandCollapse) as IExpandCollapseProvider;
                if (provider == null)
                    return;
    
                EventHandler[] handler = {null};    // array usage prevents access to modified closure
                handler[0] = new EventHandler(delegate
                {
                    if (!AssociatedObject.IsDropDownOpen || AssociatedObject.ItemContainerGenerator.Status != GeneratorStatus.ContainersGenerated)
                        return;
    
                    double largestWidth = 0;
                    foreach (var item in AssociatedObject.Items)
                    {
                        var comboBoxItem = AssociatedObject.ItemContainerGenerator.ContainerFromItem(item) as ComboBoxItem;
                        if (comboBoxItem == null)
                            continue;
    
                        comboBoxItem.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
                        if (comboBoxItem.DesiredSize.Width > largestWidth)
                            largestWidth = comboBoxItem.DesiredSize.Width;
                    }
    
                    AssociatedObject.Width = desiredWidth + largestWidth;
    
                    // Remove the event handler.
                    AssociatedObject.ItemContainerGenerator.StatusChanged -= handler[0];
                    AssociatedObject.DropDownOpened -= handler[0];
                    provider.Collapse();
                });
    
                AssociatedObject.ItemContainerGenerator.StatusChanged += handler[0];
                AssociatedObject.DropDownOpened += handler[0];
    
                // Expand the comboBox to generate all its ComboBoxItem's. 
                provider.Expand();
            }
        }
    }
    

提交回复
热议问题