How do I Bind to a DataView instead of a DataTable

G

Guest

I have a strongly typed dataset that I have been able to bind to a DataGrid
and other associated controls such that selecting a name in the DataGrid
displays the record in the associated controls using DataBinding and the
CurrencyManager. Add, Update and Delete are all working great.

Above the DataGrid I have 26 LinkLabels A-Z where (hopefully) the user will
be able to filter the names in the DataGrid.

I'm pretty sure I need to use a DataView in order to filter the records
based on the users Index (A-Z) selection but I am confused as to how to bind
everything to a DataView instead of the DataTable.

My Strongly Typed DataSet is goDS.

I use the following sample code to bind the controls:
txtFirstName.DataBindings.Add("Text", goDS, "tblGuests.FirstName")

To bind the DataGrid I use:
grd.SetDataBinding(goDS, "tblGuests")

To retrieve the CurrencyManager I use:
CType(BindingContext(goDS, "tblGuests"), CurrencyManager)

How can I bind everything to a DataView instead of a DataTable and still
have it all work in concert?

Any help would be most appreciated.
 
G

Guest

Jay,
When you bind to a DataTable, in reality you are binding to a DataView. Use
DataTable.DefaultView to get the DataView. Use
DataTable.DefaultView.RowFilter and DataTable.DefaultView.Sort to filter and
sort the DataView.

Regards,
Phil.
 
G

Guest

Based on the information below I have everything working except for one thing
- when I change the RowFilter on the DataView contained in the
DataViewManager with

goDVM.DataViewSettings(goDS.tblGuests).RowFilter = "LastName like 'A*'"

the grid does NOT reflect the filter. Calling the CurrencyManagers Refresh
method does not do the trick either.

If I set the RowFilter up before binding the grid it works but I need to
change it dynamically. Anybody know what I'm missing?

How to Bind to a DataView instead of a DataTable:
================================
You can use a DataViewManager to manage view settings for all the tables in
a DataSet. If you have a control that you want to bind to multiple tables,
such as a grid that navigates relationships, a DataViewManager is ideal.

To create the DateViewManager:

Dim moDVM As DataViewManager = New DataViewManager(goDS)

To bind the controls use:
txtFirstName.DataBindings.Add("Text", goDVM, "tblGuests.FirstName")

To bind the grid use:
grd.SetDataBinding(goDVM, "tblGuests")

To obtain the Currency Manager:
CType(BindingContext(goDVM, "tblGuests"), CurrencyManager)
 
G

Guest

Jay,
I've tried setting dataViewManager.DataViewSettings[ dataTable ].RowFilter
and get the same result as you.

Try goDS.tblGuests.DefaultView.RowFilter = "LastName like 'A*'" instead.
This should work if your dataGrid is bound to the default dataView.

If you are using creating your own dataViews, try (in C#)

DataView dataView = (DataView)((CurrencyManager)dataGrid1.BindingContext[
dataGrid1.DataSource, dataGrid1.DataMember ]).List;
dataView.RowFilter = "LastName like 'A*'"

Regards,
Phil.
 
G

Guest

Phil

As you suggested Binding to the Tables Default View and manipulating it's
RowFilter property does indeed cause the grid to respond correctly.

I have read in a number of places that the correct way to bind is:
txtBox.DataBinding.Add("Text", MyDataSet, "MyTable.MyField")
grd.SetDataBinding(MyDataSet, "MyTable")
CType(BindingContext(MyDataSet, "MyTable"), CurrencyManager)

If you bind using the DataViewManager this syntax is preserved:
txtBox.DataBinding.Add("Text", MyDataViewManager, "MyTable.MyField")
grd.SetDataBinding(MyDataSet, "MyTable")
CType(BindingContext(MyDataSet, "MyTable"), CurrencyManager)

If you bind using the Tables Default View you end with:
txtBox.DataBinding.Add("Text", MyTable.DefaultView, "MyField")
grd.DataSource = MyTable.DefaultView
CType(BindingContext(goDS.tblTasks.DefaultView), CurrencyManager)

If I remember correctly the reason for binding the recommended way is
because the code generators do it that way and if you mix the two methods it
can cause problems.

Perhaps I will start a new thread on why the grid does not reflect the
DataView when binding with the DataViewManager.

Thanks for your help.


Phil Williams said:
Jay,
I've tried setting dataViewManager.DataViewSettings[ dataTable ].RowFilter
and get the same result as you.

Try goDS.tblGuests.DefaultView.RowFilter = "LastName like 'A*'" instead.
This should work if your dataGrid is bound to the default dataView.

If you are using creating your own dataViews, try (in C#)

DataView dataView = (DataView)((CurrencyManager)dataGrid1.BindingContext[
dataGrid1.DataSource, dataGrid1.DataMember ]).List;
dataView.RowFilter = "LastName like 'A*'"

Regards,
Phil.

Jay Pondy said:
Based on the information below I have everything working except for one thing
- when I change the RowFilter on the DataView contained in the
DataViewManager with

goDVM.DataViewSettings(goDS.tblGuests).RowFilter = "LastName like 'A*'"

the grid does NOT reflect the filter. Calling the CurrencyManagers Refresh
method does not do the trick either.

If I set the RowFilter up before binding the grid it works but I need to
change it dynamically. Anybody know what I'm missing?

How to Bind to a DataView instead of a DataTable:
================================
You can use a DataViewManager to manage view settings for all the tables in
a DataSet. If you have a control that you want to bind to multiple tables,
such as a grid that navigates relationships, a DataViewManager is ideal.

To create the DateViewManager:

Dim moDVM As DataViewManager = New DataViewManager(goDS)

To bind the controls use:
txtFirstName.DataBindings.Add("Text", goDVM, "tblGuests.FirstName")

To bind the grid use:
grd.SetDataBinding(goDVM, "tblGuests")

To obtain the Currency Manager:
CType(BindingContext(goDVM, "tblGuests"), CurrencyManager)
 
G

Guest

I have a related but different question. I'm trying to limit modofocation
access to a "tree" of datatables in a dataset, being shown in a datagrid. I
want a class of users of my app to be able to see but not add/edit/delete
data. I tried setting the .AllowNew/Edit/Delete properties to false on the
DefaultView of each of the datatables. This has no effect. Does anyone know
how to do this?
 
C

ClayB [Syncfusion]

You can try to do this dynamically as you navigate to each child table in
the DataGrid.Navigate event.

private void dataGrid1_Navigate(object sender, NavigateEventArgs ne)
{
CurrencyManager cm = this.dataGrid1.BindingContext[dataGrid1.DataSource,
dataGrid1.DataMember] as CurrencyManager;
DataView dv = cm.List as DataView;
dv.AllowEdit = false;
Console.WriteLine(dv.Table.TableName);
}


==============
Clay Burch, .NET MVP

Visit www.syncfusion.com for the coolest tools
 
G

Guest

Thanks Clay,
This does indeed work, with a little code to enforce the edit rules
*before* any navigation occurs. Clearly in your example I am modifying a
different DataView than the default DataView on each of the underlying tables
in my datasource. I find the CurrencyManager a little confusing and have
avoided it when possible, but it seems that in order to reasonably exploit
the functionality of WinForms in .NET, it can not be avoided :(

Thanks again,
Tyson

ClayB said:
You can try to do this dynamically as you navigate to each child table in
the DataGrid.Navigate event.

private void dataGrid1_Navigate(object sender, NavigateEventArgs ne)
{
CurrencyManager cm = this.dataGrid1.BindingContext[dataGrid1.DataSource,
dataGrid1.DataMember] as CurrencyManager;
DataView dv = cm.List as DataView;
dv.AllowEdit = false;
Console.WriteLine(dv.Table.TableName);
}


==============
Clay Burch, .NET MVP

Visit www.syncfusion.com for the coolest tools

Tyson Kamp said:
I have a related but different question. I'm trying to limit modofocation
access to a "tree" of datatables in a dataset, being shown in a datagrid.
I
want a class of users of my app to be able to see but not add/edit/delete
data. I tried setting the .AllowNew/Edit/Delete properties to false on the
DefaultView of each of the datatables. This has no effect. Does anyone
know
how to do this?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top