Forum Discussion

Sweez's avatar
Sweez
Contributor
2 months ago
Solved

Dynamic Grids

I am looking for anyone with some experience with Dynamic Grids or are aware of any good documentation.  There is very little in the OS documention beyond how to create the component and shell of a service.  I am looking for any examples of how to actually create one.  Right now I have a dynamic grid that produces nothing.  It calles the WsasDynamicGrid class but I have no idea  what to put in the functions.  I think Dynamic Grids will be helpful in my usecase but can't get off the ground with a basic example to explore its possibilities.  Thanks in advance.

  • It sounds like you have a grid component attached to a dynamic grid class, but you aren't sure what to do next. There are two functions that you will probably want to connect inside your dynamic grid class. The first one defines and loads your grid. In C#, it would look something like:

    public XFDynamicGridGetDataResult GetDynamicGridData(SessionInfo si, BRGlobals brGlobals, DashboardWorkspace workspace, DashboardDynamicGridArgs args)
    {
    	//Define the columns for the grid, similar to the grid view component's column format in the user interface
    	List<XFDynamicGridColumnDefinition> columnDefinitions =
    	[
    		new XFDynamicGridColumnDefinition()
    		{
    			ColumnName = "RowId",
    			IsVisible = TriStateBool.FalseValue,
    		},
    		new XFDynamicGridColumnDefinition()
    		{
    			ColumnName = "DataColumn",
    			IsVisible = TriStateBool.TrueValue,
    			Description = "My Label",
    			AllowUpdates = TriStateBool.TrueValue,
    		}
    	];
    
    	//Get the data you want to put in the grid
    	var gridData = _gridDataAdapter.GetAllRows();
    
    	// Create the XFTable
    	XFDataTable xfTable = new(si, gridData, [], 1000);
    
    	//Send the result to the interface component
    	var taskResult = new XFDynamicGridGetDataResult
    	{
    		DataTable = xfTable,
    		ColumnDefinitions = columnDefinitions,
    		AccessLevel = DataAccessLevel.AllAccess
    	};
    	return taskResult;
    }
    

    The second function you likely want is the save function, which determines what happens to the changes you made to the data in the grid in the user interface when you want to apply those changes back to the source data. In C#, it would look something like:

    public XFDynamicGridSaveDataResult SaveDynamicGridData(SessionInfo si, BRGlobals brGlobals, DashboardWorkspace workspace, DashboardDynamicGridArgs args)
    {
    	//Check if there are changes
    	DashboardDynamicGridSaveDataArgs saveDataArgs = args.SaveDataArgs;
    	if (saveDataArgs == null)
    	{
    		return null;
    	}
    
    	// Get the edited rows
    	List<XFEditedDataRow> editedDataRows = saveDataArgs.EditedDataRows;
    	if (editedDataRows == null || editedDataRows.Count == 0)
    	{
    		return null;
    	}
    
    	//You can use a message string to return a message when you are done
    	var message = string.Empty;
    
    	//Apply the logic for changes
    	foreach (var editedDataRow in editedDataRows)
    	{
    		//This is an example of how to differeniate the different types of changes
    		//You might also use if-then-else or other types of logic
    		//This switch statement will check the value of each row's InsertUpdateOrDelete property
    		//It will then find the matching case and continue. The break statement tells it to
    		//exit the switch.
    		switch (editedDataRow.InsertUpdateOrDelete)
    		{
    			case DbInsUpdateDelType.Delete:
    				//Do delete logic
    				break;
    			case DbInsUpdateDelType.Update:
    				//Do update logic
    				break;
    			case DbInsUpdateDelType.Insert:
    				//Do insert logic
    				break;
    		
    		}
    	}
    
    	// Return status - this example always returns success and will show a message if you set one
    	// You can write logic to return how many rows were deleted, updated, or inserted, or include
    	// error handling or whatever you like
    	XFDynamicGridSaveDataResult result = new()
    	{
    		SaveDataTaskResult = new XFDynamicGridSaveDataTaskResult()
    		{
    			IsOK = true,
    			ShowMessageBox = message != string.Empty,
    			Message = message
    		}
    	};
    
    	return result;
    }

    These code samples will need to be tailored to your environment, however hopefully it gives you the starting point you are looking for.

8 Replies

  • Kit's avatar
    Kit
    Icon for OneStream Employee rankOneStream Employee

    It sounds like you have a grid component attached to a dynamic grid class, but you aren't sure what to do next. There are two functions that you will probably want to connect inside your dynamic grid class. The first one defines and loads your grid. In C#, it would look something like:

    public XFDynamicGridGetDataResult GetDynamicGridData(SessionInfo si, BRGlobals brGlobals, DashboardWorkspace workspace, DashboardDynamicGridArgs args)
    {
    	//Define the columns for the grid, similar to the grid view component's column format in the user interface
    	List<XFDynamicGridColumnDefinition> columnDefinitions =
    	[
    		new XFDynamicGridColumnDefinition()
    		{
    			ColumnName = "RowId",
    			IsVisible = TriStateBool.FalseValue,
    		},
    		new XFDynamicGridColumnDefinition()
    		{
    			ColumnName = "DataColumn",
    			IsVisible = TriStateBool.TrueValue,
    			Description = "My Label",
    			AllowUpdates = TriStateBool.TrueValue,
    		}
    	];
    
    	//Get the data you want to put in the grid
    	var gridData = _gridDataAdapter.GetAllRows();
    
    	// Create the XFTable
    	XFDataTable xfTable = new(si, gridData, [], 1000);
    
    	//Send the result to the interface component
    	var taskResult = new XFDynamicGridGetDataResult
    	{
    		DataTable = xfTable,
    		ColumnDefinitions = columnDefinitions,
    		AccessLevel = DataAccessLevel.AllAccess
    	};
    	return taskResult;
    }
    

    The second function you likely want is the save function, which determines what happens to the changes you made to the data in the grid in the user interface when you want to apply those changes back to the source data. In C#, it would look something like:

    public XFDynamicGridSaveDataResult SaveDynamicGridData(SessionInfo si, BRGlobals brGlobals, DashboardWorkspace workspace, DashboardDynamicGridArgs args)
    {
    	//Check if there are changes
    	DashboardDynamicGridSaveDataArgs saveDataArgs = args.SaveDataArgs;
    	if (saveDataArgs == null)
    	{
    		return null;
    	}
    
    	// Get the edited rows
    	List<XFEditedDataRow> editedDataRows = saveDataArgs.EditedDataRows;
    	if (editedDataRows == null || editedDataRows.Count == 0)
    	{
    		return null;
    	}
    
    	//You can use a message string to return a message when you are done
    	var message = string.Empty;
    
    	//Apply the logic for changes
    	foreach (var editedDataRow in editedDataRows)
    	{
    		//This is an example of how to differeniate the different types of changes
    		//You might also use if-then-else or other types of logic
    		//This switch statement will check the value of each row's InsertUpdateOrDelete property
    		//It will then find the matching case and continue. The break statement tells it to
    		//exit the switch.
    		switch (editedDataRow.InsertUpdateOrDelete)
    		{
    			case DbInsUpdateDelType.Delete:
    				//Do delete logic
    				break;
    			case DbInsUpdateDelType.Update:
    				//Do update logic
    				break;
    			case DbInsUpdateDelType.Insert:
    				//Do insert logic
    				break;
    		
    		}
    	}
    
    	// Return status - this example always returns success and will show a message if you set one
    	// You can write logic to return how many rows were deleted, updated, or inserted, or include
    	// error handling or whatever you like
    	XFDynamicGridSaveDataResult result = new()
    	{
    		SaveDataTaskResult = new XFDynamicGridSaveDataTaskResult()
    		{
    			IsOK = true,
    			ShowMessageBox = message != string.Empty,
    			Message = message
    		}
    	};
    
    	return result;
    }

    These code samples will need to be tailored to your environment, however hopefully it gives you the starting point you are looking for.

  • Thanks.  Good luck with your testing.  You example got me started and working!

  • Quick question, what kind of object is "gridData".  At first I thought t was a DataTable but GetAllRows is not a valid function for the oject as far as I can tell.

    • Kit's avatar
      Kit
      Icon for OneStream Employee rankOneStream Employee

      You are right to expect that it is a DataTable. The example I gave is a slimmed down version of some code I'm currently working on. In that code, my _gridDataAdapter is a class I wrote with some data retrieval and manipulation functions, one of which is GetAllRows, which returns a DataTable of all the rows in the table in the datasource. I believe you could substitute any data retrieval that returns a DataTable.

  • Sweez's avatar
    Sweez
    Contributor

    Kt​ I have been making good progress with building out a dynamic grid.  The only issue I have is trying to get pagination to work.  It am controlling the MaxNumRowsInResult within a XFDataTable contructor.  The only place I can see where I have any control over pagination is a XFDataTable contructor that also excepts a page number, besides a max rows in result integer.  It works if i populate the page manually but I can not figure out how to get the page number from the DashboardDynamicGridArgs values so I can make this work dynamcially.  Have you tried this at all?

    • Kit's avatar
      Kit
      Icon for OneStream Employee rankOneStream Employee

      Oh yes, good question. I have a few extra things I added to my GetDynamicGridData function that aren't included in the original answer. I do this at the top:

       DashboardDynamicGridGetDataArgs getDataArgs = args.GetDataArgs;
       int pageSize = args.GetDataArgs.PageSize;
       int page = args.GetDataArgs.StartRowIndex / pageSize + 1;

      Which gets the size of the page and the "start row index" from the GetDataArgs object. The start row index is the number of the first row of the page, so you can see that I do a little math here to determine the page number. If the page size is 1000 and the start index is 1000, the page is (1000/1000) + 1 = 2. You might be thinking, wait, shouldn't the start row index of the second page be 1001? In this case, row indexes start at 0, so the first page is 0-999 and the second page will be 1000 - 1999.

      Sounds like that's probably all you need, but in case you are wondering what I do for the data -- I give those values to the function that retrieves the data, and that's what I put in the output table:

      var gridData = _gridAdapter.GetPagedData(pageSize, page);
      XFDataTable xfTable = new(si, gridData, [], pageSize);