Share via


WFP DataGrid with Dynamic Columns and Rows and how to bind them to XAML without fixed properties

Question

Wednesday, July 22, 2020 9:43 AM

Hallo

I hope somebody can assist with some guidance on the below:

Our Data in SQl looks as below:

The PigeonLocation consist of the following information: 01 - area ID, 01- Zone Position, 01 - Row and 01 is the Column. (01010101) as per red arrow below. This can grow to many columns or Rows depending on the setup. Each of these cells will then be populated by the OrderAllocation.

Previously we used a Windows Form DataGridView with a manipulated DataTable to suit the above requirement. (Output as per below).

   public class ActiveWallViewModel
    {        
        public DataTable GetActiveWall()
        {
            var locationsFromSql = new tb_ProdPigeonStatusSql();
            var dt = new DataTable("Data From SQL");
            var wallTemplate = new DataTable("New Empty Wall ");
            var wallPopulated = new DataTable();
            var dg = new DataGridView();
            int maxRows = 0;
            int maxCol = 0;
            int maxZones = 0;

            dt = locationsFromSql.SelectAllRecords();

            maxRows = GetMaxWithParameters.GetMaxNumber(dt, 4, 2, 3);
            maxCol = GetMaxWithParameters.GetMaxNumber(dt,6, 2, 3);
            maxZones = GetMaxWithParameters.GetMaxNumber(dt, 2, 2, 3);
            // Get max Columns and rows                       

            wallTemplate = WallConfigurators.Logic.TableMatrix.CreateSetTableMatrix("New Empty Wall", maxCol, maxRows);
            wallPopulated = PopulateWallWithOrders(wallTemplate, dt);
            dg.DataSource = wallPopulated;

            return wallPopulated;
        }

        public DataTable PopulateWallWithOrders(DataTable EmptyWall, DataTable TableData)
        {
            var populatedWall = new DataTable();
            var dg = new DataGridView();
            populatedWall = EmptyWall;
            int rowCounter = 0;
            string pigeonLocation = "";
            int currentRow = 0;
            int currentColumn = 0;

            foreach(DataRow dr in TableData.Rows)
            {
                pigeonLocation = (TableData.Rows[rowCounter][3]).ToString();
                currentRow = (Convert.ToInt32(pigeonLocation.Substring(4, 2))-1);
                currentColumn = Convert.ToInt32(pigeonLocation.Substring(6, 2));                

                if (TableData.Rows[rowCounter][7].ToString().Length != 0)
                {
                    populatedWall.Rows[currentRow][currentColumn] = TableData.Rows[rowCounter][7].ToString();
                }
                else
                {
                    populatedWall.Rows[currentRow][currentColumn] = 0;
                }
                rowCounter++;
            }            
            populatedWall.TableName = "Populated Wall";
            return populatedWall;
        }        
    }
}

We starting using WPF and the databinding on the datagrid is something I cannot get my head around, the issue is the Row and Columns cannot be fixed, so trying to create a modelview object with fixed Records is going to be a issue. 

creating a class as below is not going to work, because there could be undefined amount of both.

public class PigeonLocations
{
    public int PigeonRow {get; set}
    public int PigeonColumns {get; set;}
}

Second issue is to Bind these Headers to the Path=xxx for the Properties, because this can change.

Hope somebody can just give us some guidelines, our data is correct in a datatable, just need to find a way to use databinding on the WPF XAML that is not fixed to a property?

labjac

All replies (4)

Wednesday, July 22, 2020 2:00 PM

Hello,

Here is a pattern to create dynamic columns on this page, search for 

I'd then dynamically generate the columns like this:

Which is at the bottom of the page.

Notes:

  • As per above you don't bind with XAML when dynamic columns are needed.
  • The above example uses classes, not DataTable where with WPF this is the preferred way to interact with data. 

Please remember to mark the replies as answers if they help and unmarked them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.

NuGet BaseConnectionLibrary for database connections.

StackOverFlow


Wednesday, July 22, 2020 2:08 PM

Please post questions related to WPF in the WPF forums over on Microsoft Q&A.

Michael Taylor http://www.michaeltaylorp3.net


Wednesday, July 22, 2020 2:45 PM

Hallo Michael

At this moment I'm not sure if it's going to be a WPF or a C# question. I will repost in WPF after this question which will determine which side this question should be.

labjac


Wednesday, July 22, 2020 2:51 PM

Thank Karen

I've looked at the page you've send.

Just got a question then, will the below code not be correct, this only needs to display a "wall" no edit no interface with the operators, it just updates a status view part of the process, This is data we get from SQL.

 private void WallSetupButton_Click(object sender, RoutedEventArgs e)
        {
            var activeWall = new ActiveWallViewModel();

            WallGrid.ItemsSource = activeWall.GetActiveWall().DefaultView;       
           
        }

Then one last question following on the above.

I need to format some of the cells different colour depending if they are blank and if they got OrderAllocation values. Will it be possible to customize the datagrid in another class and pass it back to the WPF form as a DataGrid that's already formatted?

WallGrid = PopulatedGrid;

Apologies for all the question, I'm not use to the way things are done in XAML and WPF it's a steep learning curve with a very different thinking of normal way we use to do things. still trying to understand the MVVM patterns..

labjac