I have two GridViews on my .aspx page and both have different selectMethod, different data but having same HeaderTemplate. I want my .aspx will have only one gridView but different datasources. Is There any Possible way to accomplish this task.
Hello If You Have Multiple Data source You may use condition that which data source list you want to bind to your gridview
In this case you can use dynamic list to bind your data source dynamically at run time as your header field is same if your data field name is same then dynamic list will be perfect for you.
I am not sure that if you used BoundField or templatefield or directly binding the datasource
As you didnt post your code i am posting a sample code for you hope you can find out something through this
//Suppose YOur Lists are List1 and List2 then
If(Condition1==true)
{
List1 // Your datasource list
List<dynamic> data = new List<dynamic>();
foreach(var data in List1)
{
data.Add(new {
Name =data.Name,
Address = data.Address
});
}
GridView1.DataSource = data
GridView1.DataBind();
}
///For Condition 2
If(Condition2==true)
{
List2 // Your second datasource list
List<dynamic> data = new List<dynamic>();
foreach(var data in List2){
data.Add(new {
Name =data.Name,
Address = data.Address
});
}
GridView1.DataSource = data
GridView1.DataBind();
}
Create an intermediate variable to hold your merged data, then fetch your retrieved data into it (from both select methods you have), then assign this variable value to showing grid *.DataSource and then call the *.DataBind(); method.
P.S. Make sure when merging the two source to have the same schema, otherwise you will have to loop on every set of results to extract it and merge it manually with the other set to have your new standard schema which should be rendered in GridView then.
Related
I have the following code that dynamically creates columns within a WPF GridView control, the header names come from a string[] which is stored in a List<string[]> named data_org
GridView gv = tabell.View as GridView;
foreach (string s in data_org.ElementAt(0))
{
gv.Columns.Add(new GridViewColumn { Header = s });
}
Is there a way to add data while I'm creating the columns? I've searched for ways of doing it in the add column statement but can't find a way.
gv.Columns.Add(new GridViewColumn{Header = s, **statement to add data to column**});
My data is stored in another List<float[]>, where each item float[] represents a column. Do I have to do something to handle that data type (float[]), too?
You do not add data items directly to the columns of a GridView. Instead, you set the ItemsSource of the associated ListView, which is tabell in your case.
tabell.ItemsSource = /* Set a binding or assign an items collection. */;
Then you would create bindings for each column to the corresponding properties on your data items that should be displayed in the columns using DisplayMemberBinding.
var gridViewColumn = new GridViewColumn
{
Header = s,
DisplayMemberBinding = new Binding(/* Binding property path / name of the property. */);
};
As you only have a list of floats for each column, you should create a suitable data item type first. The ItemsSource expects a list of items that contain properties for each column, it represents a row.
What you have to do now is:
Create a row data type that contains properties for each column
public class MyDataItem
{
public float Number { get; }
// ...properties for other columns..
}
Create a collection of these data items with data from you float lists.
var myDataItemList = new List<MyDataItem>();
// ...create data items, add your data and add the items to the list.
Assign the list as items source of the ListView.
tabell.ItemsSource = myDataItemList;
Add display member bindings for each column.
var gridViewColumn = new GridViewColumn
{
Header = s,
DisplayMemberBinding = new Binding(nameof(MyDataItem.Number));
};
Then it should work. However, I recommend you to have a look at the MVVM design pattern.
I have 2 listBoxes with BindingLists as their data sources. The idea is to make a List builder (as MSDN names it), where first listBox shows currently added columns and second listBox shows the rest of available columns. First list contains ViewColumn objects, while the other list contains strings.
I load chosen columns into first listBox from database and then I want to load the rest of available columns into the second listBox (the list itself comes from another place in database). Considering there are no limits on the number of columns, I want to do that in the fastest way possible - what would that be?
Here's some code to visualize that:
ViewTable _view;
BindingList<ViewColumn> _viewColumns = new BindingList<ViewColumn>();
BindingList<string> _detailsColumns = new BindingList<string>();
void CustomInitialize()
{
_view = //get view and its columns
_viewColumns = new BindingList<ViewColumn>(_view.Columns);
listBox_CurrentColumns.DataSource = _viewColumns;
listBox_CurrentColumns.DisplayMember = "Name";
var detailsTable = //get the list of available columns
foreach (var row in detailsTable)
{
//TODO: if _viewColumns does not contain this value, add it to _detailsColumns
_detailsColumns.Add(row.ColumnName);
}
listBox_AvailableColumns.DataSource = _detailsColumns;
}
I think you want to do something like:
_detailsColumns = _allColumns.Except(_viewColumns.Select(c => c.Name))
This should get you all entries in the _allColumns collection excluding the entries in the _viewColumns collection.
I assume here that _allColumns contains the overall collection of possible columns.
I am working on a windows application using .net 2.0. The UI appl has a datagrid and the data will be populated from the XML file.
The data grid has more than 500 rows. Sorting functionality has implemented. but customer still wants a find option or a search functionality on one of the columns with a text box where user is going to enter first 3 letters and it has to search in the grid and has to show the related rows that starts with the give search criteria.
Any suggestions pls how to implement this....
Thanks
You can use a Filter option in the BindingSource object.
private BindingSource dashBoardBindingSource = new BindingSource();
dashBoardBindingSource.DataSource=<<data source items>>;
dashBoardBindingSource.Filter="Column Name=textbox.text";
datagrid.DataSource = dashBoardBindingSource;
Store off your full collection of data, and then when the filter needs to be performed, create the filtered collection and bind the filtered collection to the grid. Just wire up appropriate text changed events to your filter box, calling FilterGridData. It works nicely when filtering via multi-column as well. Oh, and you don't have to use BindingList here. Use whatever data source you want to bind to the grid - the core of this is just "create the filtered collection by filtering with LINQ."
BindingList<Foo> _allFoos;
private void LoadData(IEnumerable<Foo> dataToDisplayInGrid)
{
this._allFoos = new BindingList<Foo>(dataToDisplayInGrid.ToList());
this.FilterGridData(string.Empty);
}
private void FilterGridData(string filterText)
{
BindingList<Foo> filteredList = null;
if (!string.IsNullOrEmpty(filterText))
{
string lowerCaseFilterText = filterText.ToLower();
IList<Foo> filteredItems = this._allFoos.Where(x => (x.Name ?? string.Empty).ToLower().Contains(lowerCaseFilterText)).ToList();
filteredList = new BindingList<Foo>(filteredItems);
}
else
{
filteredList = new BindingList<Foo>(this._allFoos);
}
dataGrid.DataSource = filteredList;
}
I want to be able to bind a List to multiple DataGridViews such that manipulation through one of the gridviews would be propogated to all other gridviews.
List<Domain> data;
1st approach:
BindingList<Domain> list = new ..;
data.ForEach( d => { list .Add(d); } );
grid1.DataSource = list;
grid2.DataSource = list;
This didn't work. The grids share properties other than the data.
2nd approach:
BindingList<Domain> list1 = new ..;
BindingList<Domain> list2 = new ..;
data.ForEach( d => { list1.Add(d); list2.Add(d); } );
grid1.DataSource = list1;
grid2.DataSource = list2;
This approach works for updates. However, adds and deletes weren't propograted.
3rd approach:
BindingList<Domain> list = new ..;
data.ForEach( d => { list .Add(d); } );
BindingSource ds1 = new BindingSource();
BindingSource ds2 = new BindingSource();
ds1.DataSource = list;
ds2.DataSource = list;
grid1.DataSource = ds1;
grid2.DataSource = ds2;
This propogates adds and deletes, however, when a new row is added to 1 view, but not yet commited, an empty row is displayed in all other grids. Seems like a new record is inserted into the List before the editing completes.
How can I properly bind multiple datagridviews to one List? (This is extremely easy in Flex.) I'd appreciate any reference to the relevant section in MDSN.
I made a little test app, just to make sure that sharing a binding source was possible the way I remembered. You can find it here (for at least 30 days).
What I found that propbably caused your problem is that all your grids probably have adding/deleting rows enabled. A new row in grid1 is displayed as a new row in grid2, but grid2 (quite unnecessarily) displays a template row below that.
I made a little main window with a read-only grid on a binding source and an edit dialog with an editable grid on the same binding source. The binding source is the only wiring between the two, no event handling to signal updates, no reassigning of datasources. Everything is synced perfectly, even the current row (because of the CurrencyManager). A new row in the dialog only shows as one empty row in the 'main' window.
Hope this helps, and is not over-simplified.
I am new to windows application. I need to add rows in the DataGrid dynamically which has person data. when i do the following is see only the last person in the last row. i see rows populating but with no data. If i do a break on the first fetch i do get the right one. But something is wrong. Any ideas
foreach (var p in personList)
{
gvAdminSummary.Rows.Add(new DataGridViewRow());
gvAdminSummary.Rows[gvAdminSummary.Rows.Count-1].Cells[0].Value = p.FName;
gvAdminSummary.Rows[gvAdminSummary.Rows.Count - 1].Cells[1].Value = p.LName;
gvAdminSummary.Rows[gvAdminSummary.Rows.Count - 1].Cells[2].Value = p.PNo;
}
The DataGridRowView.Add method accepts string arrays:
gvAdminSummary.Rows.Add( { p.FName, p.LName, p.PNo });
Likely, though, there's a better solution for you in binding the grid directly to your person list.
This may not be the right approach. Create a BindingSource and bind a collection of your objects to it. Then bind the BindingSource to the Grid's data source. Make sure your objects implement INotifyPropertyChanged. This way, whenever, you add an object to the collection, or change a property within your object, it'll automatically reflect in the grid.
I don't know about DataGridView, but if you want to stick to inserting data into the control directly, why not use ListView instead? It has an API more suited to your current needs or way of doing things.
Either
gvAdminSummary.Datasource = persons;
gvAdminSummary.databind();
Or
foreach (var p in personList)
{
DataGridViewRow dr = new DataGridViewRow();
dr.cells.add(new datagridcell()) etc.. populate cells
gvAdminSummary.Rows.add(dr);
}