【问题标题】:Get selected row item in DataGrid WPF在 DataGrid WPF 中获取选定的行项
【发布时间】:2011-04-24 05:41:06
【问题描述】:

我有一个DataGrid,绑定到数据库表,我需要在DataGrid中获取选中行的内容,例如我想在MessageBox中显示选中行的内容。

DataGrid 的示例:

所以,如果我选择第二行,我的 MessageBox 必须显示类似:646 Jim Biology

【问题讨论】:

    标签: wpf datagrid selecteditem


    【解决方案1】:

    你的前台代码:

    • 设置你的模型命名空间xmlns:viewModel="clr-namespace:CPL3_workstation.MVVM.ModelViews.Tables"
    • 设置xmlns:d="http://schemas.microsoft.com/expression/blend/2008",因为d:DataContext="{d:DesignInstance...}
    <DataGrid d:DataContext="{d:DesignInstance viewModel:TestViewModel, IsDesignTimeCreatable=True}"
              ItemsSource="{Binding Rows}"
              SelectedItem="{Binding Selector}">
        <DataGrid.Columns>
            <DataGridTextColumn
                Binding="{Binding Content1}"
                Header="Столбец 1" />
            <DataGridTextColumn
                Binding="{Binding Content2}"
                Header="Столбец 2" />
            <DataGridTextColumn
                Binding="{Binding Content3}"
                Header="Столбец 3" />
        </DataGrid.Columns>
    </DataGrid>
    

    您的ViewModel 和下面的Model

    namespace CPL3_workstation.MVVM.ModelViews.Tables
    {
        public class TestViewModel
        {
            public IEnumerable<TestModel> Rows { get; set; }
    
            public TestModel Selector
            {
                get => selector;
                set => selector = value;
            }
    
            private TestModel selector;
    
            public TestViewModel()
            {
                Rows = new List<TestModel>
                {
                    new TestModel{ Content1 = "one", Content2 = "two", Content3 = "three" },
                    new TestModel{ Content1 = "one", Content2 = "two", Content3 = "three" },
                    new TestModel{ Content1 = "one", Content2 = "two", Content3 = "three" },
                    new TestModel{ Content1 = "one", Content2 = "two", Content3 = "three" }
                };
            }
        }
    
        public class TestModel
        {
            public string Content1 { get; set; }
            public string Content2 { get; set; }
            public string Content3 { get; set; }
        }
    }
    

    如您所见,SelectedItem 绑定到模型类型的 Selector 属性。

    【讨论】:

    • 感谢您翻译答案,现在全球社区可以从您的知识和经验中受益。欢迎来到 SO!
    【解决方案2】:

    我得到了这样的东西:

    private void DataGrid_SelectionChanged(object sender, SelectionChangedEventArgs e) {
    
        DataGrid dg = (DataGrid)sender;
    
        DataRowView selectedRow = dg.SelectedItem as DataRowView;
    
        if(selectedRow != null) {
            txtXXX.Text = selectedRow["xxx"].ToString();
            txtYYY.Text = selectedRow["yyy"].ToString();
            txtZZZ.Text = selectedRow["zzz"].ToString();
        }
    
    }
    

    【讨论】:

      【解决方案3】:

      您可以使用SelectedItem 属性来获取当前选定的对象,然后您可以将其转换为正确的类型。例如,如果您的 DataGrid 绑定到 Customer 对象的集合,您可以这样做:

      Customer customer = (Customer)myDataGrid.SelectedItem;
      

      或者,您可以将SelectedItem 绑定到您的源类或ViewModel

      <Grid DataContext="MyViewModel">
          <DataGrid ItemsSource="{Binding Path=Customers}"
                    SelectedItem="{Binding Path=SelectedCustomer, Mode=TwoWay}"/>
      </Grid>
      

      【讨论】:

      • 第二个正是我想要的。谢谢!
      • 如何从给定的替代方式获取数据?
      • 第二个效果很好,补充一点可能对像我这样刚开始使用 wpf 的人有所帮助。在这个问题中,我们正在查看类 Customer。如果您没有为行定义类 DataRowView 作为 System.Data 中的数据类型。
      【解决方案4】:

      这里有很多可能适用于特定上下文的答案,但我只是试图获取所选行中第一个单元格的文本值。虽然这里接受的答案对我来说是最接近的,但它仍然需要创建一个类型并将行转换为该类型。我一直在寻找一个更简单的解决方案,这就是我想出的:

      MessageBox.Show(((DataRowView)DataGrid.SelectedItem).Row[0].ToString());

      这给了我所选行中的第一列。希望这对其他人有帮助。

      【讨论】:

      • 当然这是个人喜好问题,但我个人更喜欢接受的答案,因为它基于标准 API 并且更易于阅读 Customer customer = (Customer)myDataGrid.SelectedItem; — 一条线解决方案,清晰和平原。没有(((,没有索引Row[0],没有ToString()——太多的额外操作无法通过一个命令获得API给你的东西——SelectedItem
      • 这是假设您有一个“客户”类。如果您的 DataGrid 是从数据库查询中填充的,但 DataGrid 中的行没有特定的类,则接受的答案不起作用(除非我遗漏了什么)。也许对我来说更好的解决方案是创建这样一个类,但对于我不认为自己重用的东西,这似乎是多余的。
      【解决方案5】:

      @Krytox 用 MVVM 回答

          <DataGrid 
              Grid.Column="1" 
              Grid.Row="1"
              Margin="10" Grid.RowSpan="2"
              ItemsSource="{Binding Data_Table}"
              SelectedItem="{Binding Select_Request, Mode=TwoWay}" SelectionChanged="DataGrid_SelectionChanged"/>//The binding
      
      
      
          #region View Model
          private DataRowView select_request;
          public DataRowView Select_Request
          {
              get { return select_request; }
              set
              {
                  select_request = value;
                  OnPropertyChanged("Select_Request"); //INotifyPropertyChange
                  OnSelect_RequestChange();//do stuff
              }
           }
      

      【讨论】:

        【解决方案6】:

        您还可以:

        DataRowView row = dataGrid.SelectedItem as DataRowView;
        MessageBox.Show(row.Row.ItemArray[1].ToString());
        

        【讨论】:

        • 第一行之后的行为空。需要什么额外的代码才能完成这项工作? (从设计的角度来看,不需要额外的代码,但显然 WPF 设计得不好)
        【解决方案7】:

        如果您使用 MVVM 模式,您可以将您的 VM 的 SelectedRecord 属性与 DataGrid 的 SelectedItem 绑定,这样您的 VM 中始终拥有 SelectedValue。 否则,您应该使用 DataGrid 的 SelectedIndex 属性。

        【讨论】:

        • 我不使用 MVVM,我只是从 WPF/C#/.NET 开始。如果我写«ContentDataGrid.SelectedIndex»,我会在 DataGrid 中获得所选行的索引,我不需要索引,而是实际值,例如 «646 Jim Biology»。那么我怎样才能得到它呢?
        • 您应该考虑使用绑定对象,以便可以绑定数据网格的 SelectedItem 属性。在您的情况下,您应该尝试导航到 Datagrid 属性以了解它是否存储了选定的项目属性。
        • +1。第一句话正是我要找的!
        • SelectedRecord 属性?我假设我必须自己设置它。任何建议或代码示例都会很棒
        • @ema ,如果能提供代码示例就好了。
        【解决方案8】:

        使用您的模型类来获取从数据网格中选择的行值,例如,

                XDocument xmlDoc = XDocument.Load(filepath);
        
                if (tablet_DG.SelectedValue == null)
                {
                    MessageBox.Show("select any record from list..!", "select atleast one record", MessageBoxButton.OKCancel, MessageBoxImage.Warning);
                }
                else
                {
                    try
                    {
                        string tabletID = "";
        
                         /*here i have used my model class named as TabletMode*/
        
                        var row_list = (TabletModel)tablet_DG.SelectedItem; 
                         tabletID= row_list.TabletID;
        
                        var items = from item in xmlDoc.Descendants("Tablet")
                                    where item.Element("TabletID").Value == tabletID
                                    select item;
        
                        foreach (var item in items)
                        {
                            item.SetElementValue("Instance",row_list.Instance);
                            item.SetElementValue("Database",row_list.Database);
                        }
        
                        xmlDoc.Save(filepath);
                        MessageBox.Show("Details Updated..!"
                        + Environment.NewLine + "TabletId: " +row_list.TabletID + Environment.NewLine
                        + "Instance:" + row_list.Instance + Environment.NewLine + "Database:" + row_list.Database, "", MessageBoxButton.YesNoCancel, MessageBoxImage.Information);
                    }
        
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.StackTrace);
                    }
                }
        

        【讨论】:

          【解决方案9】:

          在我尝试了 Fara 的答案后才发现这个,但它对我的项目不起作用。只需将列从“数据源”窗口拖放到标签或文本框。

          【讨论】:

            【解决方案10】:

            这在这个 DataGrid dg 中非常简单,项目类填充在 datagrid 中,listblock1 是一个基本框架。

            private void DataGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
                {
                    try
                    {
                        var row_list = (Item)dg.SelectedItem;
                        listblock1.Content = "You Selected: " + row_list.FirstName + " " + row_list.LastName;
                    }
                    catch { }
            
                }
                public class Item
                {
                    public string FirstName { get; set; }
                    public string LastName { get; set; }
                }
            

            【讨论】:

              【解决方案11】:
              private void Fetching_Record_Grid_MouseDoubleClick_1(object sender, MouseButtonEventArgs e)
              {
                  IInputElement element = e.MouseDevice.DirectlyOver;
                  if (element != null && element is FrameworkElement)
                  {
                      if (((FrameworkElement)element).Parent is DataGridCell)
                      {
                          var grid = sender as DataGrid;
                          if (grid != null && grid.SelectedItems != null && grid.SelectedItems.Count == 1)
                          {
                              //var rowView = grid.SelectedItem as DataRowView;
                              try
                              {
                                  Station station = (Station)grid.SelectedItem;
                                  id_txt.Text =  station.StationID.Trim() ;
                                  description_txt.Text =  station.Description.Trim();
                              }
                              catch
                              {
              
                              }
                          }
                      }
                  }
              }
              

              【讨论】:

                【解决方案12】:

                如果我选择第二行 -

                 Dim jason As DataRowView
                
                
                    jason = dg1.SelectedItem
                
                    noteText.Text = jason.Item(0).ToString()
                

                noteText 将是 646。这是 VB,但你懂的。

                【讨论】:

                  【解决方案13】:

                  好吧,我会提出适合我的类似解决方案。

                   private void DataGrid1_SelectionChanged(object sender, SelectionChangedEventArgs e)
                          {
                              try
                              {
                                  if (DataGrid1.SelectedItem != null)
                                  {
                                      if (DataGrid1.SelectedItem is YouCustomClass)
                                      {
                                          var row = (YouCustomClass)DataGrid1.SelectedItem;
                  
                                          if (row != null)
                                          {
                                              // Do something...
                  
                                              //  ButtonSaveData.IsEnabled = true;
                  
                                              //  LabelName.Content = row.Name;
                  
                                          }
                                      }
                                  }
                              }
                              catch (Exception)
                              {
                              }
                          }
                  

                  【讨论】:

                    【解决方案14】:
                    public IEnumerable<DataGridRow> GetDataGridRows(DataGrid grid)
                    {
                        var itemsSource = grid.ItemsSource as IEnumerable;
                        if (null == itemsSource) yield return null;
                        foreach (var item in itemsSource)
                        {
                            var row = grid.ItemContainerGenerator.ContainerFromItem(item) as DataGridRow;
                            if (null != row) yield return row;
                        }
                    }
                    
                    private void DataGrid_Details_SelectionChanged(object sender, SelectionChangedEventArgs e)
                    {
                        try
                        {           
                            var row_list = GetDataGridRows(DataGrid_Details);
                            foreach (DataGridRow single_row in row_lis)
                            {
                                if (single_row.IsSelected == true)
                                {
                                    MessageBox.Show("the row no."+single_row .GetIndex ().ToString ()+ " is selected!");
                                }
                            }
                    
                        }
                        catch { }
                    }
                    

                    【讨论】:

                      猜你喜欢
                      • 2014-12-04
                      • 2016-10-13
                      • 2013-10-14
                      • 1970-01-01
                      • 2020-02-20
                      • 1970-01-01
                      • 2015-06-12
                      • 2016-08-11
                      相关资源
                      最近更新 更多