开发者

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)

Thanks to H.B.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜