WPF-set button arrangement

Use view model and data binding to implement the function of displaying buttons by category. Below is a simple example that demonstrates how to display different buttons by category on button click in WPF.

First, you need a view model that contains the button data and the currently selected category. Use an MVVM framework such as MVVM Light or Stylet to manage view models. Here is an example:

1.View layer: First implement the horizontal arrangement of buttons

Function 1:

 <Grid>
        <Button Content="Button 1" HorizontalAlignment="Left" Margin="10,10,0,1016" Command="{Binding ShowCategory1Command}" Grid.Row="0"/ >
        <Button Content="Button 2" HorizontalAlignment="Left" Margin="92,10,0,1016" Command="{Binding ShowCategory2Command}" Grid.Row="0"/ >
        <Button Content="Button 3" HorizontalAlignment="Left" Margin="165,10,0,1016" Command="{Binding ShowCategory3Command}" Grid.Row="0"/ >
        <UniformGrid Background="#FF919CF7" Margin="619,14,285,809">
            <!-- ItemsControl used to generate buttons -->
            <ItemsControl ItemsSource="{Binding DisplayedButtons}" BorderThickness="0">
                <!-- Set the ItemsPanel of ItemsControl to VirtualizingStackPanel and arrange it horizontally -->
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <VirtualizingStackPanel Orientation="Horizontal"/>
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
                <!-- Set the style, data binding, etc. of each button -->
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <Button Content="{Binding ButtonText}"
                        Command="{Binding DataContext.ButtonClickCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}"
                        Margin="5"
                        Width="100"
                        Height="30"/>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>
        </UniformGrid>
    </Grid>

Function 2: If you want to use UniformGrid nested inside ItemsControl to generate buttons with four rows and four columns, you can use the following

Code:

 <Grid>
        <Button Content="Button 1" HorizontalAlignment="Left" Margin="10,10,0,1016" Command="{Binding ShowCategory1Command}" Grid.Row="0"/ >
        <Button Content="Button 2" HorizontalAlignment="Left" Margin="92,10,0,1016" Command="{Binding ShowCategory2Command}" Grid.Row="0"/ >
        <Button Content="Button 3" HorizontalAlignment="Left" Margin="165,10,0,1016" Command="{Binding ShowCategory3Command}" Grid.Row="0"/ >
        <UniformGrid Rows="4" Columns="4" Background="#FF919CF7" Margin="619,14,285,809">
            <!-- ItemsControl used to generate buttons with four rows and four columns -->
            <ItemsControl ItemsSource="{Binding DisplayedButtons}" BorderThickness="0" Margin="0,0,-633,-194">
                <!-- Set the ItemsPanel of ItemsControl to UniformGrid to ensure a button grid of four rows and four columns -->
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <UniformGrid Rows="4" Columns="4"/>
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
                <!-- Set the style, data binding, etc. of each button -->
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <Button Content="{Binding ButtonText}"
                        Command="{Binding DataContext.ButtonClickCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}"
                        Margin="5"
                        Width="100"
                        Height="30"/>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>
        </UniformGrid>

    </Grid>

2.ViewModel layer:

In this example, CeshiModel represents the button’s data model, including the button text and the category it belongs to. CeshiViewModel includes a DisplayedButtons property that stores the currently displayed buttons, and three commands, ShowCategory1Command and ShowCategory2Command, ShowCategory3Command is used to display different category buttons.

using ExperimentalPlatforms.Models;
using GalaSoft.MvvmLight.Command;
using Stylet;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows.Input;

namespace ExperimentalPlatforms.ViewModels.Windows
{
    public class CeshiViewModel:Screen
    {
        private ObservableCollection<CeshiModel> allButtons;
        private ObservableCollection<CeshiModel> displayedButtons;
        private string selectedCategory;
        public ICommand ShowCategory1Command { get; private set; }
        public ICommand ShowCategory2Command { get; private set; }
        public ICommand ShowCategory3Command { get; private set; }
        public CeshiViewModel()
        {
            //Initialize button data (here you can load button data from the data source)
            allButtons = new ObservableCollection<CeshiModel>
            {
                new CeshiModel { ButtonText = "Button 1", Category = "Category 1" },
                new CeshiModel { ButtonText = "Button 2", Category = "Category 2" },
                new CeshiModel { ButtonText = "Button 3", Category = "Category 3" },
                new CeshiModel { ButtonText = "Button 3", Category = "Category 3" },
                 new CeshiModel { ButtonText = "Button 3", Category = "Category 3" },
                 new CeshiModel { ButtonText = "Button 3", Category = "Category 3" },
                  new CeshiModel { ButtonText = "Button 3", Category = "Category 3" },
                 new CeshiModel { ButtonText = "Button 3", Category = "Category 3" },
                 new CeshiModel { ButtonText = "Button 3", Category = "Category 3" },
                //Add more buttons
            };

            // Display all buttons in initial state
            displayedButtons = new ObservableCollection<CeshiModel>(allButtons);

            //Initialization command
            ShowCategory1Command = new RelayCommand(ShowCategory1);
            ShowCategory2Command = new RelayCommand(ShowCategory2);
            ShowCategory3Command = new RelayCommand(ShowCategory3);
        }

        public ObservableCollection<CeshiModel> DisplayedButtons
        {
            get { return displayedButtons; }
            set
            {
                if (displayedButtons != value)
                {
                    displayedButtons = value;
                    OnPropertyChanged(nameof(DisplayedButtons)); // Trigger property change notification
                }
            }
        }
        private void ShowCategory1()
        {
            // Only show buttons for Category 1
            DisplayedButtons = new ObservableCollection<CeshiModel>(allButtons.Where(b => b.Category == "Category 1"));
        }

        private void ShowCategory2()
        {
            // Only show buttons for Category 2
            DisplayedButtons = new ObservableCollection<CeshiModel>(allButtons.Where(b => b.Category == "Category 2"));
        }
        private void ShowCategory3()
        {
            // Only show buttons for Category 2
            DisplayedButtons = new ObservableCollection<CeshiModel>(allButtons.Where(b => b.Category == "Category 3"));
        }
    }
}

3.Model layer:

CeshiModel is a collection containing button data models. Each button data model includes Category and ButtonText attributes, which are used to distinguish the category and text of the button.

 public class CeshiModel
    {
        public string ButtonText { get; set; }
         public string Category { get; set; } //Category
    }