How do I correctly use the selected items property of a datagrid following mvvm?

I have a couple of datagrid's in my WPF app like
<DataGrid ItemsSource="{Binding FilteredBills}" AutoGenerateColumns="False"
IsReadOnly="True"
SelectionUnit="FullRow"
HeadersVisibility="Column"
Name="IMPGrid">
<DataGrid.Columns>
<DataGridTextColumn
Header="Bill No."
Binding="{Binding Path=BillNo, Mode=OneWay}"
Width="275"
IsReadOnly="True" />
<DataGridTextColumn
Header="Bill Date"
Binding="{Binding Path=BillDt, Mode=OneWay}"
Width="75"
IsReadOnly="True" />
<DataGridTextColumn
Header="Amount"
Binding="{Binding Path=Amt, StringFormat=N2, Mode=OneWay}"
Width="75"
IsReadOnly="True" />
</DataGrid.Columns>
</DataGrid>
<DataGrid ItemsSource="{Binding AdjBills}" AutoGenerateColumns="False"
SelectionUnit="FullRow"
HeadersVisibility="Column"
Name="EXPGrid">
<DataGrid.Columns>
<DataGridTextColumn
Header="CNDN No."
Binding="{Binding Path=CndnNo, Mode=OneWay}"
Width="275"
IsReadOnly="True" />
<DataGridTextColumn
Header="Date"
Binding="{Binding Path=Date, Mode=OneWay}"
Width="275"
IsReadOnly="True" />
<DataGridTextColumn
Header="Amount"
Binding="{Binding Path=Value, Mode=OneWay}"
Width="275"
IsReadOnly="True" />
</DataGrid.Columns>
</DataGrid>
The properties representing both the datagrid's columns reside in the same class
public class Bills : ViewModelBase
{
...
private string _billNo;
public string BillNo
{
get
{
return _billNo;
}
set
{
SetValue(ref _billNo, value);
}
}
private string _billDt;
public string BillDt
{
get
{
return _billDt;
}
set
{
SetValue(ref _billDt, value);
}
}
...
private double _value;
public double Value
{
get
{
return _value;
}
set
{
SetValue(ref _value, value);
}
}
}
Now, what I'm trying to do is when I selected rows from both the datagrid's and hit the Preview button like this it should generate a PDF like this and if I choose only the first datagrid rows like this it should generate a PDF like this
Previously when I did not use the MVVM pattern I would use these helper classes (using itext5), call it in the button click event like invoice.GenerateDocument(filePath, infoText, lblCity, billsGrid, adjGrid);
and it would work fine but now when I try to use it in my current app it is showing error
System.Exception: 'Unable to cast object of type 'DG2PDF.Bills' to type 'System.Data.DataRowView'.'
in the line foreach (DataRowView row in gridView.SelectedItems)
of the below section
foreach (DataRowView row in gridView.SelectedItems)
{
for (int x = 0; x < 3; x++)
{
table.AddCell(new iTextSharp.text.Phrase(row.Row.ItemArray[x].ToString()));
}
_rowNumber++;
}
If I change the foreach loop to foreach (Bills bill in gridView.SelectedItems)
then I would have to hardcode the properties like table.AddCell(new iTextSharp.text.Phrase(bill.BillNo.ToString()));
which is a problem as the gridView represents both datagrid's and their properties/columns are different.
How do I fix this ?
Hi @Jiale Xue - MSFT ,
Thanks for your reply. If I try to use
foreach (Bills bill in (Bills)gridView.SelectedItems)
I get the errorError CS1579 foreach statement cannot operate on variables of type 'Bills' because 'Bills' does not contain a public instance or extension definition for 'GetEnumerator'
, usingforeach (Bills bill in gridView.SelectedItems)
works fine but the problem is that then I would have to hardcode the properties. Anyways, I think I'm not explaining the issue here correctly.Previously when I iterated through the selected rows (without MVVM) like :
I didn't had to worry about hard coding the property names as it would use
ItemArray[x]
to get the column values of each row regardless of which datagrid's row its iterating through (if your look at my original question both datagrids IMPGrid and EXPGrid have different property names/columns).To make you understand better/test it I'm sharing this github link
Hi @Jiale Xue - MSFT , did my above explanation help you understand the problem I'm facing ?
Hi @don bradman ,I see that you used
command.CommandText = "SELECT * FROM supps";
What is the structure and data of the table ofsupps
?Hello @Jiale Xue - MSFT , Here you go
Hi @don bradman ,What is the relationship between the datasheet
cndndata
andbilldata
? When filtering to displayIMPGrid DataGrid
data, how shouldexPGrid
data be displayed? Is the code in your link a successful preview of the table in the image you showed? What is the code of causing the"System.Exception: 'Unable to cast object of type 'DG2PDF.Bills' to type 'System.Data.DataRowView'."
?Hi @Jiale Xue - MSFT , The SQLite database tables
billdata
andcndndata
are two different tables, there are no foreign keys or anything like that. When I choose an item from the combo box then the datagrid IMPGrid is filled with filtered data by matching theParty
column of thebilldata
with selected combo box item (SelectedCBItem
) and the datagrid EXPGrid is filled with filtered data by matching theVendor
column of thecndndata
table with the same selected combo box item (SelectedCBItem
).The code in my link is not a successful preview of the table in the image I showed, thats the problem...
Like I mentioned in my initial post the line of code
foreach (DataRowView row in gridView.SelectedItems)
is giving the errorNow I've commented this portion and tried replacing it with
which works when I only select rows from the IMPGrid but when I also select rows form the EXPGrid it then throws the error
it is throwing this error because the columns of EXPGrid are bound to different properties i.e. CndnNo, Date and Value instead of BillNo, BillDt and Amt. Hope you get a decent picture now.
So, how do I solve this?
Sign in to comment
Hi @don bradman ,
I added the data table without reproducing your problem, I added
AddTable1
andGenerateTable1
and usedGenerateTable1
to generate the second table in the preview.Write a separate method for the second table:
Then add it to The GenerateTable:
Best Regards,
Jiale
If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".
Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.
Sign in to comment
0 additional answers
Sort by: Most helpful
Activity