none
XAML ListView - How to get SelectedItem

    Question

  •  

    Hi,

     

    I fill a WPF ListView using LINQ for SQL select statement. The list is displayed okay - how do I get the original LINQ DataContext object from the ListView.SelectedItem property?

     

    The ListView XAML code is shown below:

    <ListView Height="460" Name="listView1" Width="426.795" SelectionMode="Single" ItemsSource="{Binding}" DisplayMemberPath="Call_ID" IsSynchronizedWithCurrentItem="True" SelectionChanged="listView1_SelectionChanged">

    <ListView.View>

    <GridView>

    <GridViewColumn Header="ID" DisplayMemberBinding="{Binding Path=Call_ID}" Width="50"/>

    <GridViewColumn Header="Customer Name" DisplayMemberBinding="{Binding Path=Customer_Name}" Width="200"/>

    <GridViewColumn Header="Telephone No." DisplayMemberBinding="{Binding Path=Customer_TelephoneNo}" Width="100"/>

    <GridViewColumn Header="Contact Name" DisplayMemberBinding="{Binding Path=Customer_Contact}" Width="140"/>

    <GridViewColumn Header="Status" DisplayMemberBinding="{Binding Path=Status_Description}" Width="80"/>

    </GridView>

    </ListView.View>

    </ListView>

     

    The code below is used to propulate the list view:

    // Load Calls using LINQ

    DataClassesDataContext context = new DataClassesDataContext("Server=localhost\\SQLEXPRESS;Database=DemoDB;Trusted_Connection=yes;");

    var data = from c in context.Calls

    join p in context.Customers on c.Customer_ID equals p.Customer_ID

    join s in context.Status on c.Status equals s.Status_ID

    join o in context.Operators on c.Operator_ID equals o.Operator_ID

    where c.Status == 'O' || c.Status == 'P'

    orderby c.Status, c.Call_ID

    select new { c.Call_ID, p.Customer_ID, p.Customer_Name, p.Customer_TelephoneNo, p.Customer_Contact, s.Status_Description, o.Operator_ShortName };

    this.DataContext = data;

     

    In the ListView_SelectionChanged event I would like to retrieve the context.Calls object and inspect the Call_ID property - how do I do this?

     

    Any help is greatly appreciated?

     

    Graham.

    Wednesday, January 09, 2008 1:06 PM

Answers

  • Well, I think you need to define a class (let's call it CallCustomerInfo) which has all the properties (c.Call_ID, p.Customer_ID, p.Customer_Name, p.Customer_TelephoneNo, p.Customer_Contact, s.Status_Description, o.Operator_ShortName etc) you want to project over to the result set when using linq query. Your linq query should return a result set containing the number of CallCustomerInfo objects instead of the anonymous type objects, so in the ListView.SelectedItemChanged, you should be able to extract the selected CallCustomerInfo object by examining the listView.SelectedItem property, and grab the Call_ID and Customer_ID out of it.

    Hope this helps
    Friday, January 11, 2008 9:35 AM

All replies

  • Well, the SelectedItem will return the anonymous type object you construct from the "select new" expression, so basically based on your LINQ query expression, you cannot get the Call object.

    Instead of write something as follows:
    select new {...}

    You can write something like the following instead:
    select c;

    And even if you can the reference to each selected Call object from ListView.SelectedItem property, you still cannot get the Linq to Sql data context object, since when you use the linq query to get the result set and bind it to ListView, ListView only knows about the result set returned from linq query rather than its underlying data context object.

    Could you please elaborate a bit about your scenario? what do you want to achieve from the SelectionChanged event?

    Hope this helps
    Friday, January 11, 2008 5:31 AM
  • Hi,

     

    Thanks for the information.

     

    I'm trying to use the SelectionChanged event to extract the Call_ID and Customer_ID values from the selected row so as other detail views, else where on the page, can be populated.

     

    So what your saying above is - if I select the "c" fields (single table without joins) then I can retrieve the details using the Call class - so the joins cause the problem as I do not have a class that matches the selected field layout.

     

    Thanks

    Graham

     

     

     

    Friday, January 11, 2008 8:29 AM
  • Well, I think you need to define a class (let's call it CallCustomerInfo) which has all the properties (c.Call_ID, p.Customer_ID, p.Customer_Name, p.Customer_TelephoneNo, p.Customer_Contact, s.Status_Description, o.Operator_ShortName etc) you want to project over to the result set when using linq query. Your linq query should return a result set containing the number of CallCustomerInfo objects instead of the anonymous type objects, so in the ListView.SelectedItemChanged, you should be able to extract the selected CallCustomerInfo object by examining the listView.SelectedItem property, and grab the Call_ID and Customer_ID out of it.

    Hope this helps
    Friday, January 11, 2008 9:35 AM
  •  

    Thanks for the information.....

     

    Okay - I see what is required....

     

    So if I need to select fields from multiple tables I have to create a class that directly maps onto the selected fields and then amended the query to the below so the data can be cast to the correct type.

     

    IEnumerable<CallCustomerInfo> data = from c in context.Calls

    join p in context.Customers on c.Customer_ID equals p.Customer_ID

    join s in context.Status on c.Status equals s.Status_ID

    join o in context.Operators on c.Operator_ID equals o.Operator_ID

    where c.Status == 'O' || c.Status == 'P'

    orderby c.Status, c.Call_ID

    select new CallCustomerInfo { Call_ID = c.Call_ID, Customer_ID = p.Customer_ID, Customer_Name = p.Customer_Name, Customer_TelephoneNo = p.Customer_TelephoneNo, Customer_Contact = p.Customer_Contact, Status_Description = s.Status_Description, Operator_ShortName = o.Operator_ShortName };

     

    This works great......

     

    Thanks again for your help!

     

    Graham.

    Friday, January 11, 2008 9:42 AM