locked
ListView/ GridView Selection quesiton RRS feed

  • Question

  • I have a simple WPF ListView that is bound to a Dataset.  The ListView defines a number of columns using the following format:

    <Listview>

      <ListView.View>

        <GridView>

          <GridView.CellTemplate>

            <DataTemplate>

            </DataTemplate>

          <GridView.CellTemplate>

        </GridView>

      </ListView.View>

    </Listview>

    There are multiple columns.  My question is simple, If I have a button or textbox in one of the columns, and I click on on the column/row, how do I get the DataRow that is selected?  The RoutedEventArgs (in the case of clicking on a button) doesn't seem to provide that information.  If I set the IsSynchronizedWithCurrentItem Property of the View.CurrentPosition doesn't seem to report the DataRow Index of the Gridvew row index.

    Thanks.

    Monday, May 10, 2010 1:25 AM

Answers

  • You actually have to pull it from the DataContext of the Button that was clicked since the Button is a child of the row and the row's DataContext is the item in question. You can do something like this

    XAML

    <ListView x:Name="listView">
      <ListView.View>
        <GridView>
          <GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}"></GridViewColumn>
          <GridViewColumn>
            <GridViewColumn.CellTemplate>
              <DataTemplate>
                <Button Click="Button_Click">Click Me</Button>
              </DataTemplate>
            </GridViewColumn.CellTemplate>
          </GridViewColumn>
        </GridView>
      </ListView.View>
    </ListView>
    CODE

    public partial class Window1 : Window
    {
      public Window1()
      {
        InitializeComponent();
    
        listView.ItemsSource = new List<DataClass>() 
        { 
          new DataClass() { Name = "Robotuner"},
          new DataClass() { Name = "MSearles"},
        };
      }
    
      private void Button_Click(object sender, RoutedEventArgs e)
      {
        Button button = sender as Button;
        DataClass dataClass = button.DataContext as DataClass;
    
        Console.WriteLine(dataClass.Name);
      }
    }
    
    class DataClass
    {
      public string Name { get; set; }
    }

    Or if you're using commands, use CommandParameter="{Binding }".

     

    Warm regards,

    Matt

    • Proposed as answer by Matt Searles Friday, May 14, 2010 7:02 AM
    • Marked as answer by Aland Li Tuesday, May 18, 2010 2:28 AM
    Monday, May 10, 2010 1:33 AM
  • Hi Robotuner,

    You can create a CollectionViewSource to simplify this work:

        CollectionViewSource _viewSource = new CollectionViewSource();
        public Window1()
        {
          InitializeComponent(); 
          _viewSource.Source = new List<DataClass>();
          listView1.ItemsSource = _viewSource.View;
        }
    
        private void Button_Click(object sender, RoutedEventArgs e)
        {
          var item = _viewSource.View.CurrentItem;
          var index = _viewSource.View.CurrentPosition;
        }

    Let me know if this does not help.
    Aland Li


    Please mark the replies as answers if they help and unmark if they don't. This can be beneficial to other community members reading the thread.
    • Marked as answer by Aland Li Tuesday, May 18, 2010 2:28 AM
    Friday, May 14, 2010 2:47 PM

All replies

  • You actually have to pull it from the DataContext of the Button that was clicked since the Button is a child of the row and the row's DataContext is the item in question. You can do something like this

    XAML

    <ListView x:Name="listView">
      <ListView.View>
        <GridView>
          <GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}"></GridViewColumn>
          <GridViewColumn>
            <GridViewColumn.CellTemplate>
              <DataTemplate>
                <Button Click="Button_Click">Click Me</Button>
              </DataTemplate>
            </GridViewColumn.CellTemplate>
          </GridViewColumn>
        </GridView>
      </ListView.View>
    </ListView>
    CODE

    public partial class Window1 : Window
    {
      public Window1()
      {
        InitializeComponent();
    
        listView.ItemsSource = new List<DataClass>() 
        { 
          new DataClass() { Name = "Robotuner"},
          new DataClass() { Name = "MSearles"},
        };
      }
    
      private void Button_Click(object sender, RoutedEventArgs e)
      {
        Button button = sender as Button;
        DataClass dataClass = button.DataContext as DataClass;
    
        Console.WriteLine(dataClass.Name);
      }
    }
    
    class DataClass
    {
      public string Name { get; set; }
    }

    Or if you're using commands, use CommandParameter="{Binding }".

     

    Warm regards,

    Matt

    • Proposed as answer by Matt Searles Friday, May 14, 2010 7:02 AM
    • Marked as answer by Aland Li Tuesday, May 18, 2010 2:28 AM
    Monday, May 10, 2010 1:33 AM
  • Hi Robotuner,

    You can create a CollectionViewSource to simplify this work:

        CollectionViewSource _viewSource = new CollectionViewSource();
        public Window1()
        {
          InitializeComponent(); 
          _viewSource.Source = new List<DataClass>();
          listView1.ItemsSource = _viewSource.View;
        }
    
        private void Button_Click(object sender, RoutedEventArgs e)
        {
          var item = _viewSource.View.CurrentItem;
          var index = _viewSource.View.CurrentPosition;
        }

    Let me know if this does not help.
    Aland Li


    Please mark the replies as answers if they help and unmark if they don't. This can be beneficial to other community members reading the thread.
    • Marked as answer by Aland Li Tuesday, May 18, 2010 2:28 AM
    Friday, May 14, 2010 2:47 PM