Search code examples
c#wpfxamlpanel

Adding objects to WPF Panel displaying buttons


I want to add objects dynamicly to a ObservationCollection, which then should add buttons with a Content (value) of a field of the object to a panel.

App.xaml.cs using System.Windows;

namespace WpfApp1
{
    public partial class App : Application
    {

    }
}

MainWindow.xaml

<Window x:Class="WpfApp1.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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <ItemsControl Name="dashboardList">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <Button Content="{Binding Name}" />
                </DataTemplate>
            </ItemsControl.ItemTemplate>

        </ItemsControl>
    </Grid>
</Window>

DashboadViewModel.cs

using System.Collections.ObjectModel;

namespace WpfApp1
{
    public class DashboardViewModel
    {
        public ObservableCollection<Dashboard> Dashboards { get; set; }

        public DashboardViewModel()
        {
            LoadDashboards();
        }

        public void LoadDashboards()
        {
            ObservableCollection<Dashboard> dashboards = new ObservableCollection<Dashboard>();

            dashboards.Add(new Dashboard { Name = "Dashboard1" });
            dashboards.Add(new Dashboard { Name = "Dashboard2" });

            Dashboards = dashboards;
        }
    }
}

Dashboard.cs

namespace WpfApp1
{
    public class Dashboard
    {
        public string Name;
    }
}

How do I get to create the buttons, am I on the right track with the ItemControl?


Solution

  • public string Name should be changed to be a public property to support data binding:

    public class Dashboard
    {
        public string Name { get; set; }
    }
    

    Besides that, an instance of DashboardViewModel should be assigned to the Window's DataContext property and the ItemsControl's ItemsSource property should be bound like this:

    <Window ...
        xmlns:local="clr-namespace:WpfApp1">
    
        <Window.DataContext>
            <local:DashboardViewModel/>
        </Window.DataContext>
    
        <Grid>
            <ItemsControl ItemsSource="{Binding Dashboards}">
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <Button Content="{Binding Name}" />
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>
        </Grid>
    </Window>
    

    If necessary, you can access the view model instance in the Window's code behind like this:

    var vm = (DashboardViewModel)DataContext;
    vm.LoadDashboards();