How do you get values from SelectedItem in a multi-column ListView in WPF?
I have a ListView control as below
XAML
<ListView Name="myListView" MinHeight="200" FontSize="14" Style="{StaticResource DataGridS开发者_运维技巧tyle}">
<ListView.View>
<GridView>
<GridViewColumn Header="Reference Code" Width="0" DisplayMemberBinding="{Binding ReferenceCodeDescription}" HeaderContainerStyle="{StaticResource GridViewColumnHeaderStyle}"/>
<GridViewColumn Header="Description" Width="594" DisplayMemberBinding="{Binding Description}" />
</GridView>
</ListView.View>
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
</ListView>
I have populated the ListView control with data using LINQ to Entities.
Code-Behind
Dim Stk As New List(Of Stock)
Dim Ref As New List(Of ReferenceCode)
Stk = Context.Stocks.ToList
Ref = Context.ReferenceCodes.ToList
Dim mySource = From s In Stk
Join r In Ref On s.StockID Equals r.StockID
Where s.Description.ToLower.Contains(txtSearch.Text.ToLower)
Select r.ReferenceCodeDescription, s.Description
myListView.ItemsSource = mySource
My question is how do I get a reference to individal GridViewColumn items from the SelectedItem property of the ListView ?
When I try
myListView.SelectedItem
I get the entire row back (E.g: {Reference Code = Z88 , Description = OIL FILTER}
I suspect that I am using an Anonymous type as my ItemsSource and that if I used a Named Type I may be able to interrogate the SelectedItem better, but I'm not sure how to do this.
Any ideas or advice?
Create a class with the properties you need and create instances of that class in the select
part of the Linq query assigning the properties of the queried object to the properties of your new instance (an example for this can be found on MSDN as well). If you are going to reuse the created objects outside of the local scope do not use anonymous types. Then you can cast the SelectedItem
to that class and access those properties.
(I do not know if you can do this in vb.net but in this question here a method for casting an anonymous type in C# is given. (Further in C# only you could just make the item dynamic and access the properties as you see fit.))
Edit: C# Example:
public class MyItem
{
public string ReferenceCodeDescription { get; set; }
public string Description { get; set; }
}
var items = from r in ItemsA
join s in ItemsB on r.StockID equals s.StockID
select new MyItem()
{
ReferenceCodeDescription = r.ReferenceCodeDescription,
Description = s.Description
};
myListView.ItemsSource = items;
MyItem item = (MyItem)myListView.SelectedItem;
MessageBox.Show(item.Description);
The solution above looks rather verbose - here's another way that I prefer due to it's simplicity...
If attempting to access it in the xaml.vb
code:
dim myItem as DataRowView = myListView.SelectedItem
dim myColumn1 as String = myItem.Row.Item(0)
dim myColumn2 as Date = myItem.Row.Item(1)
etc.
If accessing it in the ViewModel.vb
, create a property for the DataRowView
, and in the xaml, bind the SelectedItem
to your Data Row View property. The columns in the row can then be accessed as above.
For all you endangered-species VB programmers (like me) I have converted H.B's solution to VB!
Public Class MyItem
Public Property ReferenceCodeDescription() As String
Get
Return m_ReferenceCodeDescription
End Get
Set(ByVal value As String)
m_ReferenceCodeDescription = Value
End Set
End Property
Private m_ReferenceCodeDescription As String
Public Property Description() As String
Get
Return m_Description
End Get
Set(ByVal value As String)
m_Description = Value
End Set
End Property
Private m_Description As String
End Class
Dim mySource = From r In Ref
Join s In Stk On r.StockID Equals s.StockID
Select New MyItem With { _
.ReferenceCodeDescription = r.ReferenceCodeDescription,
.Description = s.Description }
myListView.ItemsSource = mySource
Dim item As MyItem = DirectCast(myListView.SelectedItem, MyItem)
MessageBox.Show(item.Description)
精彩评论