Translate

Friday, January 3, 2014

WPF ComboBox Adjusting to Parent Grid size or Max Width of Item

I was messing around with WPF the other day and had a ComboBox as part of a grid. Instead of the ComboBox either being the max width of the cell or a set width, I wanted the ComboBox to be the max width of a child item with a maximum of the cell size (I don't want the ComboBox to overflow the cell). I came up with the code below, and can be adapted to other panel types but is focused on the ComboBox being in a cell of the Grid.
public class ComboBoxEx : ComboBox
  {
    public override void OnApplyTemplate()
    {
      base.OnApplyTemplate();

      Loaded += AdjustWidth;
      FrameworkElement element = Parent as FrameworkElement;
      if (element != null)
        element.SizeChanged += AdjustWidth;
    }

    protected override void OnVisualParentChanged(DependencyObject oldParent)
    {
      base.OnVisualParentChanged(oldParent);

      FrameworkElement element = oldParent as FrameworkElement;
      if (element != null)
        element.SizeChanged -= AdjustWidth;

      element = Parent as FrameworkElement;
      if (element != null)
        element.SizeChanged += AdjustWidth;
    }

    private double GetParentWidth()
    {
      if (Parent is Grid)
      {
        Grid grid = Parent as Grid;
        int col = (int)GetValue(Grid.ColumnProperty);

        return grid.ColumnDefinitions[col].ActualWidth;
      }
      
      Panel panel = Parent as Panel;
      return panel != null ? panel.ActualWidth : 0;
    }

    private double GetPreferredWidth()
    {
      double maxWidth = 0;

      foreach (ComboBoxItem obj in Items)
      {
        UIElement element = obj.Content as UIElement;
        if (element == null)
          continue;

        element.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
        double width = element.DesiredSize.Width;
        if (width > maxWidth)
        {
          maxWidth = width;
        }
      }

      return maxWidth;
    }

    private void AdjustWidth(object sender, EventArgs e)
    {
      double parentWidth = GetParentWidth();
      double newWidth = GetPreferredWidth();

      MinWidth = newWidth < parentWidth ? newWidth : parentWidth;
    }
  }

No comments:

Post a Comment

Codementor

Ryan Kuhn

★★★★★

Expertise