Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF ItemsControl horizontal orientation and fill parent?

I am trying to horizontally place the items in an ItemControl whilst making them fill the parent control.

Here is my XAMl:

             <ItemsControl ItemsSource="{Binding AnnualWeatherViewModels}" Visibility="{Binding IsAnnualWeatherViewModels, Converter={StaticResource VisibilityConverter}}">
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <StackPanel Orientation="Horizontal"></StackPanel>
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <V:AerosolSimpleWeatherCharacteristicsView DataContext="{Binding}"></V:AerosolSimpleWeatherCharacteristicsView>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>

The two variations I have tried for ItemsControl.ItemsPanel are:

<StackPanel Orientation="Horizontal"></StackPanel>

and:

<DockPanel LastChildFill="False"></DockPanel>

However neither achieve the desired result, the StackPanel compresses all the items and the DockPanel will either fill the space of the parent control with a large portion of space dedicated to the last item or not fill the parent space depending on the value of LastChildFill.

So how can I layout the items of my ItemsControl horizontally and have them fill the space of the parent control?

I ended up creating this custom control as sugested in the answer:

public partial class StretchingPanel : Grid
    {
        public static readonly DependencyProperty OrientationProperty =
            DependencyProperty.Register("Orientation", typeof(Orientation), typeof(StretchingPanel), new UIPropertyMetadata(System.Windows.Controls.Orientation.Horizontal));

        public static readonly DependencyProperty FillFirstItemProperty =
            DependencyProperty.Register("FillFirstItem", typeof(bool), typeof(StretchingPanel), new UIPropertyMetadata(true));

        public static readonly DependencyProperty FillFirstItemFactorProperty =
            DependencyProperty.Register("FillFirstItemFactor", typeof(double), typeof(StretchingPanel), new UIPropertyMetadata(1.8));

        public Orientation Orientation
        {
            get
            {
                return (Orientation)GetValue(OrientationProperty);
            }
            set
            {
                SetValue(OrientationProperty, value);
            }
        }

        public bool FillFirstItem
        {
            get
            {
                return (bool)GetValue(FillFirstItemProperty);
            }
            set
            {
                SetValue(FillFirstItemProperty, value);
            }
        }

        public double FillFirstItemFactor
        {
            get
            {
                return (double)GetValue(FillFirstItemFactorProperty);
            }
            set
            {
                SetValue(FillFirstItemFactorProperty, value);
            }
        }

        protected override void OnVisualChildrenChanged(DependencyObject visualAdded, DependencyObject visualRemoved)
        {
            if (Orientation == System.Windows.Controls.Orientation.Horizontal)
            {
                ColumnDefinitions.Clear();
                for (int i = 0; i < Children.Count; ++i)
                {
                    var column = new ColumnDefinition();
                    if (i == 0 && FillFirstItem)
                        column.Width = new GridLength(FillFirstItemFactor, GridUnitType.Star);
                    ColumnDefinitions.Add(column);
                    Grid.SetColumn(Children[i], i);
                }
            }
            else
            {
                RowDefinitions.Clear();
                for (int i = 0; i < Children.Count; ++i)
                {
                    var row = new RowDefinition();
                    if (i == 0 && FillFirstItem)
                        row.Height = new GridLength(FillFirstItemFactor, GridUnitType.Star);
                    RowDefinitions.Add(row);
                    Grid.SetRow(Children[i], i);
                }
            }
            base.OnVisualChildrenChanged(visualAdded, visualRemoved);
        }

        public StretchingPanel()
        {
            InitializeComponent();
        }
    }
like image 951
Alex Hope O'Connor Avatar asked May 12 '13 22:05

Alex Hope O'Connor


1 Answers

UniformGrid does the job.

        <ItemsPanelTemplate>
            <UniformGrid Rows="1"/>
        </ItemsPanelTemplate>
like image 72
lisp Avatar answered Oct 06 '22 01:10

lisp