locked
Dynamic grid row count and column count with XAML RRS feed

  • Question

  • I'm using this blog post to implement a dynamic grid.

    However, I can't seem to get it working when I change the row count and column count on my global class variables.

    I'm using the GridHelpers.cs class from the above link and my UserControl xaml looks like this

    <UserControl x:Class="WPFPurpleButtonTest.InstrumentUserControl"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
                 xmlns:local="clr-namespace:WPFPurpleButtonTest"
                 mc:Ignorable="d" 
                 d:DesignHeight="450" d:DesignWidth="800">
        <Grid>
            <Label x:Name="colourName" Content="PURPLE" HorizontalAlignment="Left" Height="93" Margin="284,88,0,0" VerticalAlignment="Top" Width="243" FontWeight="Bold" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" FontSize="50" Foreground="#FFDC00FF"/>
            <Button x:Name="testButton" Content="Button" HorizontalAlignment="Left" Margin="354,234,0,0" VerticalAlignment="Top" Width="75" Click="TestButton_Click"/>
            <Label x:Name="label" Content="Row Size" HorizontalAlignment="Left" Margin="222,296,0,0" VerticalAlignment="Top" Foreground="#FFDC00FF"/>
            <Label x:Name="label_Copy" Content="Column Size" HorizontalAlignment="Left" Margin="438,296,0,0" VerticalAlignment="Top" Foreground="#FFDC00FF"/>
            <Button x:Name="createGrid" Content="Create Grid" HorizontalAlignment="Left" Margin="357,348,0,0" VerticalAlignment="Top" Width="75" Click="CreateGrid_Click"/>
            <TextBox x:Name="rowSizeText" HorizontalAlignment="Left" Height="23" Margin="296,299,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="62"/>
            <TextBox x:Name="columnSizeText" HorizontalAlignment="Left" Height="23" Margin="528,300,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="62"/>
            <Grid local:GridHelpers.RowCount="{Binding RowCount}"
          local:GridHelpers.ColumnCount="{Binding ColumnCount}" ></Grid>
        </Grid>
    </UserControl>

    My CS code looks like this:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;

    namespace WPFPurpleButtonTest
    {
        /// <summary>
        /// Interaction logic for InstrumentUserControl.xaml
        /// </summary>
        public partial class InstrumentUserControl : UserControl
        {
            // We should put this in a separate user control, but for now for testing
            // let's put the grid configuration in here
    public int RowCount
    {
    get { return (int)GetValue(GridHelpers.RowCountProperty); }
    set { SetValue(GridHelpers.RowCountProperty, value); }
    }
    public int ColumnCount
    {
    get { return (int) GetValue(GridHelpers.ColumnCountProperty); }
    set { SetValue(GridHelpers.ColumnCountProperty, value); }
    }

            public InstrumentUserControl()
            {
                InitializeComponent();
                DataContext = this;
            }

            private void TestButton_Click(object sender, RoutedEventArgs e)
            {
                MessageBox.Show("HELLO!", "Greetings", MessageBoxButton.OK, MessageBoxImage.Information);
            }

            private void CreateGrid_Click(object sender, RoutedEventArgs e)
            {
                if (int.TryParse(rowSizeText.Text, out int rowResult))
                {
                    RowCount = rowResult;
                }

                if (int.TryParse(columnSizeText.Text, out int columnResult))
                {
                    ColumnCount = rowResult;
                }
            }
        }
    }

    RowCountChanged function obj is "InstrumentUserControl" not "Grid" - that's line 40 in Gridhelpers.cs. Returns on line 41 because of this
    • Edited by Sushi567 Tuesday, July 30, 2019 12:18 PM
    Tuesday, July 30, 2019 12:15 PM

All replies

  • Hi   Sushi567,

    >>However, I can't seem to get it working when I change the row count and column count on my global class variables.

    I'm using the GridHelpers.cs class from the above link and my UserControl xaml looks like this

    If you want to change the Grid row  and column dynamically. You need to try the following steps.

    1: Create a custom Grid with RowCountC and ColumnCountC DependencyProperty.

         public class MyGrid : Grid
        {
    
            #region RowCount Property
    
            /// <summary>
            /// Adds the specified number of Rows to RowDefinitions. 
            /// Default Height is Auto
            /// </summary>
            public static readonly DependencyProperty RowCountCProperty =
                DependencyProperty.Register(
                    "RowCountC", typeof(int), typeof(MyGrid),
                     new FrameworkPropertyMetadata((int)0,
                    FrameworkPropertyMetadataOptions.None,
                    new PropertyChangedCallback(RowCountChanged)));
    
            // Get
            public static int GetRowCountC(DependencyObject obj)
            {
                return (int)obj.GetValue(RowCountCProperty);
            }
    
            // Set
            public static void SetRowCountC(DependencyObject obj, int value)
            {
                obj.SetValue(RowCountCProperty, value);
            }
    
            // Change Event - Adds the Rows
            public static void RowCountChanged(
                DependencyObject obj, DependencyPropertyChangedEventArgs e)
            {
                if (!(obj is Grid) || (int)e.NewValue < 0)
                    return;
    
                Grid grid = (Grid)obj;
                grid.RowDefinitions.Clear();
    
                for (int i = 0; i < (int)e.NewValue; i++)
                    grid.RowDefinitions.Add(
                        new RowDefinition() { Height = GridLength.Auto });
    
                
            }
    
            #endregion
    
            #region ColumnCount Property
    
            /// <summary>
            /// Adds the specified number of Columns to ColumnDefinitions. 
            /// Default Width is Auto
            /// </summary>
            public static readonly DependencyProperty ColumnCountCProperty =
                DependencyProperty.Register(
                    "ColumnCountC", typeof(int), typeof(MyGrid),
                  new FrameworkPropertyMetadata((int)0,
                    FrameworkPropertyMetadataOptions.None,
                    new PropertyChangedCallback(ColumnCountChanged)));
    
            // Get
            public static int GetColumnCountC(DependencyObject obj)
            {
                return (int)obj.GetValue(ColumnCountCProperty);
            }
    
            // Set
            public static void SetColumnCountC(DependencyObject obj, int value)
            {
                obj.SetValue(ColumnCountCProperty, value);
            }
    
            private static void ColumnCountChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
            {
                if (!(obj is Grid) || (int)e.NewValue < 0)
                    return;
    
                Grid grid = (Grid)obj;
                grid.ColumnDefinitions.Clear();
    
                for (int i = 0; i < (int)e.NewValue; i++)
                    grid.ColumnDefinitions.Add(
                        new ColumnDefinition() { Width = GridLength.Auto });
    
            }
            #endregion
    
        }

    2: In your UserControl implement the INotifyPropertyChanged.

    UserControlGrids : UserControl,INotifyPropertyChanged
        public event PropertyChangedEventHandler PropertyChanged;
    
            private void RaiseProperChanged([CallerMemberName] string caller = "")
            {
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(caller));
            }
    
    
      // let's put the grid configuration in here
            private int _RowCount;
    
            public int RowCount
            {
                get { return _RowCount; }
                set
                {
                    _RowCount = value;
                    RaiseProperChanged();
                }
            }
    
            private int _ColumnCount;
    
            public int ColumnCount
            {
                get { return _ColumnCount; }
                set
                {
                    _ColumnCount = value;
                    RaiseProperChanged();
                }
            }
    
            private void CreateGrid_Click(object sender, RoutedEventArgs e)
            {
                if (int.TryParse(rowSizeText.Text, out int rowResult))
                {
                    RowCount = rowResult;
                }
    
                if (int.TryParse(columnSizeText.Text, out int columnResult))
                {
                    ColumnCount = columnResult;
                }
    
                MessageBox.Show("Row: " + testf.RowDefinitions.Count.ToString() + " ; " + "Column: " + testf.ColumnDefinitions.Count.ToString());
            }

    3: UserControl XAML

    <Grid Margin="0,0,0,-128">
            
            <Label x:Name="colourName" Content="PURPLE" HorizontalAlignment="Left" Height="93" Margin="284,88,0,0" VerticalAlignment="Top" Width="243" FontWeight="Bold" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" FontSize="50" Foreground="#FFDC00FF"/>
            <Button x:Name="testButton" Content="Button" HorizontalAlignment="Left" Margin="354,234,0,0" VerticalAlignment="Top" Width="75" Click="TestButton_Click"/>
            <Label x:Name="label" Content="Row Size" HorizontalAlignment="Left" Margin="222,296,0,0" VerticalAlignment="Top" Foreground="#FFDC00FF"/>
            <Label x:Name="label_Copy" Content="Column Size" HorizontalAlignment="Left" Margin="438,296,0,0" VerticalAlignment="Top" Foreground="#FFDC00FF"/>
            <Button x:Name="createGrid" Content="Create Grid" HorizontalAlignment="Left" Margin="357,348,0,0" VerticalAlignment="Top" Width="75" Click="CreateGrid_Click"/>
            <TextBox x:Name="rowSizeText" HorizontalAlignment="Left" Height="23" Margin="296,299,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="62"/>
            <TextBox x:Name="columnSizeText" HorizontalAlignment="Left" Height="23" Margin="528,300,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="62"/>
    
            <local:MyGrid Background="Aqua" ShowGridLines="True" x:Name="testf" RowCountC="{Binding RowCount}" ColumnCountC="{Binding ColumnCount}"  Margin="0,384,0,0" >
                
            </local:MyGrid>
           
        </Grid>


    Besides, It would be appreciated if you could close the thread by marking helpful posts as an answer. This will help other members to find the solution quickly if they have faced the similar issue. If you have a new question you can start a new thread  with all necessary code snippets for anyone else to be able to reproduce your issue from scratch along with a detailed description about the results including any exception messages.

    Best regards

    Yong Lu


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Wednesday, July 31, 2019 3:47 AM