Row Filters on Master/Detail DataGrids

G

Guest

I have 2 Datagrids on a form in a master/detail relationship.
Master Grid Datasource is a DataView dvOrders and the Detail Grid Datasource
is the same dataview with DataMember set to the relationship
OrderOrderLineItem.

All works perfectly as long as there are rows in dvOrders.

The problem arises when a filter is applied to dvOrders which yields no
rows. The Master Datagrid rightfully displays no rows, but the Detail
Datagrid displays the first row in the OrderLineItem table.

Is there a way to set up the databinding to have the detail datagrid reflect
the fact that there are no rows associated with the master since there is no
master row?

The only way I've made the UI work is to have separate Dataviews for each
grid and manually code separate row filters for each dataview. This is not
very elegant.

Thanks,
Dave
 
C

Cor Ligthert

Dave,

There are two methods used to create Master Details Datagrids.

One is with the datarelation the other with the dataview.rowfilter.

I have now the idea that you are using to much code, because normally only
one of that is enough,

Therefore can you maybe show us a piece of code to give us an idea.

Cor
 
G

Guest

Cor,
Thanks for responding. I've extracted some code and posted it below.
This is the code that exhibits the problem of showing rows in dgOrderDetail
even
though there are no rows in the dgOrders because the RowFilter of mdvOrders
returns no rows.

I included two event responses that may have a bearing as they respond to
events fired when the Orders row changes or when the OrderDetail Column
changes.

Note that I have the Invoice and IvoiceDetail datagrids bound through the
mdvOrders dataview and they work just fine. That makes it more difficult to
figure why the OrderDetail datagrid is not working property.

Any insights will be greatly appreciated.
Thanks,
Dave

Friend mdvOrders, mdvCustomers As DataView
Friend WithEvents mcurmgrOrders As CurrencyManager
Private WithEvents mOrderDetailTable As dsOrder.OIPLineItemDataTable
Private mOrderRow As dsOrder.OrderInProcessRow

Private Sub frmWebOrders_Load(ByVal sender As Object, ByVal e As
System.EventArgs) Handles MyBase.Load
'Create the dataviews
mdvOrders = New DataView(dsOrder1.OrderInProcess)
mdvCustomers = New DataView(DSCustomer1.Customer)

'Assign the data sources
dgOrders.DataSource = mdvOrders
dgOrderDetail.DataSource = mdvOrders
dgOrderDetail.DataMember = "OrderInProcessOIPLineItem"
dgInvoices.DataSource = mdvOrders
dgInvoices.DataMember = "OrderInProcessInvoice"
dgInvoiceDetail.DataSource = mdvOrders
dgInvoiceDetail.DataMember =
"OrderInProcessInvoice.InvoiceInvoiceLineItem"

mOrderDetailTable = dsOrder1.OIPLineItem
mcurmgrOrders = Me.BindingContext(mdvOrders)

'Other initialization code
'
'***********************
End Sub

'****** mcurmgrOrders_CurrentChanged *************
' Sets mOrderRow to the newly selected order. mOrderRow used by numerous
functions in response to
' control events that work on the curently selected order.
'
' Sets filter for the Customer Dataview to the customer ID for the current
order. This is to display customer info
' for the current order in simple bound controls that are bound to the
Customer dataview
'*************************************************************
Private Sub mcurmgrOrders_CurrentChanged(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles mcurmgrOrders.CurrentChanged
If Not mcurmgrOrders.Current Is Nothing Then
mOrderRow = mcurmgrOrders.Current.Row
mdvCustomers.RowFilter = "ID = '" &
mcurmgrOrders.Current("CustomerID") & "'"
End If
End Sub

'************ mOrderDetailTable_ColumnChanged ****************
' Checks of one of several columns have been changed
' If yes, calculates Total Weight and TotalPRice
' then recalcs overall totals for the order
'**************************************************************
Private Sub mOrderDetailTable_ColumnChanged(ByVal sender As Object, _
ByVal e As System.Data.DataColumnChangeEventArgs) Handles
mOrderDetailTable.ColumnChanged
Select Case e.Column.ColumnName
Case "QtyOrdered","Price","Weight"
If Not IsDBNull(e.Row("QtyOrdered")) And Not
IsDBNull(e.Row("Price"))Then
e.Row("PriceTotal") = e.Row("QtyOrdered") * e.Row("Price")
End If
If Not IsDBNull(e.Row("QtyOrdered")) And Not
IsDBNull(e.Row("Weight"))then
e.Row("WeightTotal") = e.Row("QtyOrdered") *
e.Row("Weight")
End If
e.Row.EndEdit()
CalcOrderTotals()
End Select
End Sub
 
C

Cor Ligthert

Dave,


Private Sub mcurmgrOrders_CurrentChanged(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles mcurmgrOrders.CurrentChanged
If Not mcurmgrOrders.Current Is Nothing Then
mOrderRow = mcurmgrOrders.Current.Row
mdvCustomers.RowFilter = "ID = '" &
mcurmgrOrders.Current("CustomerID") & "'"
End If
End Sub
When I saw this than I thought "What happens if mcumgrOrders.Current is
Something?.

As it is now the rowfilter stays the same. I don't know if you do this
express, however it sounds as something you stated that did not work, I
would at least expect an else statement.

I hope this helps something,

Cor
 
G

Guest

Cor,
Good catch. I changed the code to that shown below. Unfortunately, it did
not resolve the problem. (Setting the ID to '0' guarantees a no hit since
all id's are generates using Guid.NewGuid.ToString)

If you have any other thoughts, I 'd appreciate them.

Thanks
Dave
If mcurmgrOrders.Current Is Nothing Then
mOrderRow = Nothing
mdvCustomers.RowFilter = "ID = '0'"
else
 
C

Cor Ligthert

Dave,

When I look at this code I don't understand the aspect of that customer
dataview.

Do you have for orders more customers or something?

Cor
 
G

Guest

Cor,
I have Customer BillTo and ShipTo info displayed with each order. I use
simple databinding of dvCustomers with textboxes, etc. to display the info.
Using the row filter on dvCustomers is an easy way to display the correct
customer for the selected Order.

I doubt the dvCustomers contributes to the problem. I just included it to
show why I was responding to the events.

Also, Today I tried running the code with the 2 events commented out and
still have the same results as far as the Master/Detail Grids are concerned.

Thanks,
Dave
 
C

Cor Ligthert

Dave,

I mean in this part, where you use the dataview from the customers in my
opinion to filter the detailrows from the orders. I would expect a rowfilter
on the detailview of the orders.
If Not mcurmgrOrders.Current Is Nothing Then
mOrderRow = mcurmgrOrders.Current.Row
mdvCustomers.RowFilter = "ID = '" &
mcurmgrOrders.Current("CustomerID") & "'"
End If

Cor
 
G

Guest

Cor,
Actually, that is the workaround that works.
Rather than databinding the OrderDetail through the Order Dataview, which
should work but doesn't, I have to have a separate dataview for the
OrderDetail and apply a filter to it each time the row changes on the Orders
Dataview.

Thanks for your thoughts. I've decided to live with the workaround and
accept the limitation that the Detail portion of the Master/Detail
relationship can't recognize when there is no master to provide details for.

Regards,
Dave
 
C

Cor Ligthert

Dave,
Cor,
Actually, that is the workaround that works.

I am glad that you can live with the workaround, however show next time the
part that does not work. Than it is probably easier to find why that is not
working.

:)

Cor
 
G

Guest

Cor,
Sorry for the confusion in my previous response.
The dataview from the customers is not related to the Master/Detail problem.

In the workaround that works, which I did not post, I do as you say you
would expect and use a rowfilter on the OrderDetail view. I set it to ID='0'
if no Order Rows are visible in the view or to the current row ID if one or
more are visible.

At any rate, thanks for your help.

Dave
 

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