Hello,
I would like to add a DropDownList to a WebDataGrid in each row. In order to populate the unique dropdownlist for each row I would like to use a DataTable and add the dropdown to each Row in the DataTable.
Is this possible, for example in the Aspx to have something like:
<ig:WebDataGrid ID="Datagrid" runat="server" Height="350px" Width="100%" AutoGenerateColumns="False" > <Columns> <ig:BoundCheckBoxField DataFieldName="BoundCheckBoxField_0" Key="BoundCheckBoxField_0"> <Header Text="BoundCheckBoxField_0"> </Header> </ig:BoundCheckBoxField> <ig:BoundDataField DataFieldName="Unique Key to Determine Drop Down Values" Key="Unique Key to Determine Drop Down Values"> <Header Text="Unique Key to Determine Drop Down Values"> </Header> </ig:BoundDataField> <ig:BoundDataField DataFieldName="DropDownField" Key="DropDownField"> <Header Text="DropDownField"> </Header> </ig:BoundDataField></Columns> <EditorProviders> <ig:DropDownProvider ID="DropDownFieldProvider"> <EditorControl ID="DropDownField" runat="server" DisplayMode="DropDownField" TextField="DropDownField" ValueField="DropDownField"> <DropDownItemBinding TextField="DropDownField" ValueField="DropDownField" /> </EditorControl> </ig:DropDownProvider> </EditorProviders> <Behaviors> <ig:VirtualScrolling> </ig:VirtualScrolling> </Behaviors> </ig:WebDataGrid>
and on the back end have:
protected void Datagrid_doDatabinding(){
DataTable dt = new DataTable("dt"); dt.Columns.Add(new DataColumn("Unique Key to Determine Drop Down Values", typeof(string)));
dt.Columns.Add(new DataColumn("DropDownField", typeof(WebDropDown)));
/*get unique key set from a list of relational items on the server*/ foreach (uniquekey in uniquekeyset) { DataRow row = dt.NewRow(); row["Unique Key to Determine Drop Down Values"] = uniquekey; WebDropDown NewDropDown = new WebDropDown();
NewDropDown = get_items(uniquekey); //would return the proper WebDropDown
row["DropDownField"] = NewDropDown ;
dt.Rows.Add(row); } DataView dv = new DataView(dt); PObyAssessment.DataSource = dv; PObyAssessment.DataBind();
}
Thanks for any advice on this.
Hi Marcelo,
Thank you for your examples. Though I am a bit confused I believe I have the main idea and will suggest accordingly.
1) I would like to add a DropDownList to a WebDataGrid in each row.
Setting some control ( like the DropDown) to act as an EditorProvider for a WebDataGrid column means that it will render on each row in the corresponding column cell. This is the way its working out of the box.
Setting a DropDown editor provider is as easy as the following ( it is described in details here):
<ig:BoundDataField DataFieldName="Data" Key="Data"> <Header Text="Data"> </Header></ig:BoundDataField>
<editorproviders> <ig:DropDownProvider ID="DropDownProvider1"> <editorcontrol TextField="Data" ValueField="data"> </editorcontrol> </ig:DropDownProvider> </editorproviders> <behaviors> <ig:EditingCore> <Behaviors> <ig:CellEditing> <ColumnSettings> <ig:EditingColumnSetting ColumnKey="Data" EditorID="DropDownProvider1" /> </ColumnSettings> </ig:CellEditing> </Behaviors> </ig:EditingCore> </behaviors>
In code behind the dropdown provider is bound to a data source:
protected void Page_Load(object sender, EventArgs e) { DropDownProvider dropdownprovider = (DropDownProvider)WebDataGrid1.EditorProviders["DropDownProvider1"]; dropdownprovider.EditorControl.DataSource = MakeTable(); }
I am also attaching a working sample here. Please note that in this case the DropDown is bound to the same data source field which populates the Data column in the grid. You can of course bind the dropdown to another field or another data source.
Hi Hristo,
This example makes is very good but my issue is that for each row the DropDown will need to contain unique values depending on the Item. Is the only way to do this to add a Unique DropDownProvider for each Row?
The following would be an example (adapted from your example and the following does not work but would love to figure out how it can) -- I need a situation where if WebDataGrid is populated by "MakeTable_2" and in MakeTable_2 if "MakeTable" is passed the Value "1" then the dropdown for that Row with have 20 values "Data 0" to "Data 19" and if "MakeTable" is passed the value "2" then that row would have a drop down with only "Data 0" to "Data 5"
Does this issue make sense? is there a way to do this programmatically/on the server side? Do I just need to make unique DropDownProviders for each row?
public partial class _Default : System.Web.UI.Page{ protected void Page_Load(object sender, EventArgs e) { this.WebDataGrid1.DataSource = MakeTable_2(); } private DataTable MakeTable(int x) { // Create a new DataTable. System.Data.DataTable table = new DataTable("Table"); // Declare variables for DataColumn and DataRow objects. DataColumn column; DataRow row; // Create new DataColumn, set DataType, // ColumnName and add to DataTable. column = new DataColumn(); column.DataType = System.Type.GetType("System.Int32"); column.ColumnName = "id"; column.ReadOnly = true; // Add the Column to the DataColumnCollection. table.Columns.Add(column); // Create second column. column = new DataColumn(); column.DataType = System.Type.GetType("System.Int32"); column.ColumnName = "Item"; column.AutoIncrement = false; column.Caption = "Item"; column.ReadOnly = false; column.Unique = false; // Add the column to the table. table.Columns.Add(column); // Create third column. column = new DataColumn(); column.DataType = System.Type.GetType("System.String"); column.ColumnName = "Data"; column.AutoIncrement = false; column.Caption = "Data"; column.ReadOnly = false; column.Unique = false; // Add the column to the table. table.Columns.Add(column); // Make the ID column the primary key column. DataColumn[] PrimaryKeyColumns = new DataColumn[1]; PrimaryKeyColumns[0] = table.Columns["id"]; table.PrimaryKey = PrimaryKeyColumns; if (x == 1) { for (int i = 0; i <= 20; i++) { row = table.NewRow(); row["id"] = i; row["Item"] = i; row["Data"] = "Data " + i; table.Rows.Add(row); } } if (x == 2) { for (int i = 0; i <= 5; i++) { row = table.NewRow(); row["id"] = i; row["Item"] = i; row["Data"] = "Data " + i; table.Rows.Add(row); } } return table; } private DataTable MakeTable_2() { // Create a new DataTable. System.Data.DataTable table = new DataTable("Table"); // Declare variables for DataColumn and DataRow objects. DataColumn column; DataRow row; DataRow row2; // Create new DataColumn, set DataType, // ColumnName and add to DataTable. column = new DataColumn(); column.DataType = System.Type.GetType("System.Int32"); column.ColumnName = "id"; column.ReadOnly = true; // Add the Column to the DataColumnCollection. table.Columns.Add(column); // Create second column. column = new DataColumn(); column.DataType = System.Type.GetType("System.String"); column.ColumnName = "Item"; column.AutoIncrement = false; column.Caption = "Item"; column.ReadOnly = false; column.Unique = false; // Add the column to the table. table.Columns.Add(column); // Create third column. column = new DataColumn(); column.DataType = System.Type.GetType("System.String"); column.ColumnName = "Data"; column.AutoIncrement = false; column.Caption = "Data"; column.ReadOnly = false; column.Unique = false; // Add the column to the table. table.Columns.Add(column); // Make the ID column the primary key column. DataColumn[] PrimaryKeyColumns = new DataColumn[1]; PrimaryKeyColumns[0] = table.Columns["id"]; table.PrimaryKey = PrimaryKeyColumns; row = table.NewRow(); row["id"] = 1; row["Item"] = "This is Item 1"; row["Data"] = "Select...";
DropDownProvider dropdownprovider = (DropDownProvider)WebDataGrid1.EditorProviders["DropDownProvider1"]; dropdownprovider.EditorControl.DataSource = MakeTable(1);
table.Rows.Add(row); row2 = table.NewRow(); row2["id"] = 2; row2["Item"] = "This is Item 2"; row2["Data"] = "Select...";
dropdownprovider = (DropDownProvider)WebDataGrid1.EditorProviders["DropDownProvider1"]; dropdownprovider.EditorControl.DataSource = MakeTable(2);
table.Rows.Add(row2); return table; }}
Thanks so much.
Thank you for your further explanations. There is no need to use a unique DropDown for each row. It is enough to have the same DropDown and populate it with differewnt data for each row. To achieve this we make use of the following workflow:
1) Attach to the cellEditing_EnteringEditMode, this will fire when you try to edit a cell
<CellEditingClientEvents EnteringEditMode="WebHierarchicalDataGrid1_CellEditing_EnteringEditMode" />
2) In the event handler of cellEditing_EnteringEditMode we call the loadItems method of the dropdown:
function WebHierarchicalDataGrid1_CellEditing_EnteringEditMode(sender, eventArgs) { if (eventArgs.getCell().get_column().get_key() === "Patient First Name") { var dropdowneditor2 = ig_controls.ddeditor2; var rowIndex = eventArgs.getCell().get_row().get_index(); dropdowneditor2.loadItems(rowIndex, false); } }
As you see we pass a parameter to the method, in this case the rowIndex, so we can build a logic around that. You can pass any value.
3) Calling loadItems will trigger the server event ItemsRequested, that we need to attach to:
<EditorControl ID="ddeditor2" ClientIDMode="Static" Width="200px" OnItemsRequested="ddeditor2_ItemsRequested" DropDownContainerMaxHeight="200px" EnableAnimations="False" EnableDropDownAsChild="False"> <ClientEvents DropDownOpening="WebHierarchicalDataGrid1_DropDown_DropDownOpening" /> </EditorControl>
As you see below we can make use of the rowIndex for any logic,. in this case we populate the dropdown with different date based on that.
protected void ddeditor2_ItemsRequested(object sender, EventArgs e) { int rowIndex = Int32.Parse(((Infragistics.Web.UI.ListControls.DropDownItemsRequestedEventArgs)e).Value.ToString()); // query your database using the rowIndex value, or assign datasource, or filter current dataSource, etc this.dd2.EditorControl.DataSource = MakeTable(rowIndex); this.dd2.EditorControl.ValueField = "id"; this.dd2.EditorControl.TextField = "Data"; this.dd2.EditorControl.DataBind();
}}
I am also attaching the sample for your reference. It makes use of the WebHierarchicalDataGrid, but the approach has NO different with a flat WebDataGris control. The dropdown is in the last column of the grid.
Thanks so much Hristo - I'll take a look at this today and tomorrow and see if I have any other issue that needs to be cleared up.
That's fine, you can update the thread whenever you are up to this.
Hello Hristo,
I hope you can help me with one more question on this. I've gotten the dropdowns to work correctly to show the unique data for each row. The issue now becomes that whenever attempting to select an item from the dropdown a postback is triggered and the DataGrid goes through another DataBinding and the selected value of the DropDown is effectively lost. For instance in the example you provided when I select "Data 1" after the post back the text/value for the field is still "Pat" although the dropdown will correctly display "Data 1".
Is there any way to keep this information through postback so that a user can select several different dropdowns and eventually click a button to save the values selected to a Database?
Just let me know if you need any clarification or if you have any advice on this.
In a WebDataGrid with editor providers scenario all data manipulations should be handled by the grid itself. This will involve either a Manual CRUD or Auto CRUD scenario. If it is a manual CRUD, it involves persisting the data in the RowUpdating server side event of the WebDataGrid. If the grid properly handles its data, then you will experience no issues.
This process may be affected by a postback triggered by the dropdown, and actually you do not need this postback (if you do - please explain me why, so that I can suggest accordingly) .You can control the postback triggered by the dropdown using the AutoPostBack property, which is false by default (you can even customize the postbacks behavior using the AutoPostBackflags for selection and value changing, that control whether a full or partial postback will happen). The sample I have provided uses the default value and it is recommended for the most scenarios.
Concluding the above - if you are already persisting the WebDataGrid data somehow, turning off the AutoPostBack of the drop down will solve the issue. If this is not the case, please let me know so I can suggest accordingly.
This is fine, I hope everything works well on your side.
This is great Hristo. I will be able to test it out sometime this week and confirm that all is resolved.
I have updated the sample I have initially sent to manually handle the data changes. To do this the RowUpdating event is handled ( please note that you should have AutoCRUD set to false in order to work witj the RowUpdating event). The workflow is quite mainstream, e.g.:
1) The grid data (or any other data source ) is saved into Session
2) in the RowUpdating event the data changes are manually persisted and saved into the Session again. The example is trivial with a DataSet:
protected void WebHierarchicalDataGrid1_RowUpdating(object sender, RowUpdatingEventArgs e) { ContainerGrid containerGrid = (ContainerGrid)sender;
if (containerGrid.Level == 0) { if (HttpContext.Current.Session["GridData"] != null) { DataSet ds = Session["GridData"] as DataSet; DataRow row = ds.Tables["ParentTable"].Rows.Find(e.Row.DataKey); row["Patient Last Name"] = e.Values["Patient Last Name"]; row["Patient First Name"] = e.Values["Patient First Name"]; ds.AcceptChanges();
Session["GridData"] = ds; } }
this.WebHierarchicalDataGrid1.DataSource = (DataSet)Session["GridData"]; this.WebHierarchicalDataGrid1.DataBind(); }
The same way any other data source (like the one that populates the dropdown may be handled and any changes to be persisted. The RowUpdating/RowDeleting/RowAdding server events occur at the most appropriate time in the page lifecycle and the respective data operations are recommended to be handled in those events, as demonstrated in the sample.
When I use the dropdown the 'onrowupdating' function is not firing but am not sure why (might have to do with an unbound checkbox that I've added/need in the table?)
I think the drowdown does need at least the partial postback since the values are being set on the server side programatically.
I will look into using manual CRUD and see if I can manage it okay.
Any other info, examples or tutorials you can point me to on persisting data through user changes and then saving that to a DB would be great!
Thanks so much