Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to bind an ObservableCollection<T> to a WrapPanel?

I'm using WPF. I have ObservableCollection of ToggleButton :

private ObservableCollection<ToggleButton> myg = new ObservableCollection<ToggleButton>();

and I want to bind these ObservableCollection controls(ToggleButtons) as WrapPanel childrens. Every time I use myg.Add(new ToggleButton) I want it to add control to WrapPanel automatically.

Example XAML:

<WrapPanel Name="test1">
    <!-- I want to bind (add) these controls here -->
</WrapPanel>

Is it possible, if yes - how ? Maybe there is other similar way to do that ?

like image 630
armandasalmd Avatar asked Apr 12 '16 20:04

armandasalmd


1 Answers

It is very easy but there is a little catch:

To leverage the 'observable collection' feature, one needs to bind to it but there is no property such as ItemsSource on WrapPanel.

Solution:

Use an ItemsControl and set its panel to be a WrapPanel that hosts items.

XAML

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:local="clr-namespace:WpfApplication1"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        Title="MainWindow"
        Width="525"
        Height="350"
        mc:Ignorable="d">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="1*" />
        </Grid.RowDefinitions>
        <Button Grid.Row="0"
                Click="Button_Click"
                Content="Add toggle" />
        <ItemsControl Grid.Row="1" ItemsSource="{Binding}">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <WrapPanel IsItemsHost="True" />
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
        </ItemsControl>
    </Grid>
</Window>

Code

using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Controls.Primitives;

namespace WpfApplication1
{
    public partial class MainWindow : Window
    {
        private readonly ObservableCollection<ToggleButton> _collection;

        public MainWindow()
        {
            InitializeComponent();

            _collection = new ObservableCollection<ToggleButton>();

            DataContext = _collection;
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            var toggleButton = new ToggleButton
            {
                Content = "Toggle" + _collection.Count
            };
            _collection.Add(toggleButton);
        }
    }
}

Note:

Assigning your collection to the DataContext relieves you to directly deal with your WrapPanel, the <ItemsControl Grid.Row="1" ItemsSource="{Binding}"> binds to this property by default.

like image 188
aybe Avatar answered Nov 10 '22 07:11

aybe