C# WPF DataGrid 在列中搜索值,返回行索引

Posted

技术标签:

【中文标题】C# WPF DataGrid 在列中搜索值,返回行索引【英文标题】:C# WPF DataGrid Search for a Value in a Column, Return the Row Index 【发布时间】:2015-05-05 19:18:49 【问题描述】:

我是 C# 开发的新手。在编写应用程序时,我正在学习和挣扎——最好的学习方法是:)

我希望有人能够帮助我解决我的问题。

我正在通过 dataGrid1.ItemsSource = dt.DefaultView; 填充 WPF DataGrid 然后让 DataGrid 自动为我生成列。

用户可以单击 DataGrid 中的任何行,然后将使用该行的数据填充我在 WPF UI 上的标题部分 - 这允许用户通过标题编辑该行。我不希望他们通过 DataGrid 进行编辑。

用户可以通过标题字段编辑行,然后单击更新按钮。 UPDATE 按钮将运行一个存储过程来处理记录的所有验证和更新。保存记录后,我会启动网格刷新方法。

刷新网格后,我需要能够搜索 DataGrid 上的特定列,以便选择、设置焦点并滚动到刚刚更新的行。

我在 Google 上疯狂搜索,但在 DataGrid 上找不到如何执行此操作。有一些关于如何在 DataGridView 上执行此操作的示例,这不是我正在使用的。

非常感谢任何帮助....谢谢

这是我的按钮点击代码

private void btn_Update_Click(object sender, RoutedEventArgs e)

        // variables
        bool isOkToUpdate = true;

        this.Cursor = Cursors.Wait;            

        // Validations of certain fields
        if (txt_FinanceEmpName.Text.Length > 25 )
        
            MessageBox.Show("The Finance Emp Name must not exceed 25 characters in length. " 
                + txt_FinanceEmpName.Text.Length.ToString()
                , "Maximum characters exceeded"
                , MessageBoxButton.OK, MessageBoxImage.Stop);

            isOkToUpdate = false;
        

        //
        if (isOkToUpdate == true)
        
            // create an instance
            DatabaseClass objDatabaseClass = new DatabaseClass(_connectionString);

            // if we are able to open and close the SQL Connection then proceed
            if (objDatabaseClass.CheckSQLConnection())
            
                try
                
                    // create instance of SqlConnection class. variable 'con' will hold the instance
                    SqlConnection con = new SqlConnection(_connectionString);

                    con.Open();

                    // use a using for all disposable objects, so that you are sure that they are disposed properly
                    using (SqlCommand cmd = new SqlCommand("usp_mktdata_update_cm_mktdata_emp_name_fits_to_finance", con))
                    
                        cmd.CommandType = CommandType.StoredProcedure;
                        cmd.Parameters.Add("@IdUnique", SqlDbType.Int).Value = Convert.ToInt32(txt_IdUnique.Text);
                        cmd.Parameters.Add("@FinanceEmpName", SqlDbType.VarChar).Value = txt_FinanceEmpName.Text;
                        cmd.Parameters.Add("@ADWindowsLogon", SqlDbType.VarChar).Value = _windowsUserName;
                        cmd.Parameters.Add("@ADWindowsLogonEMail", SqlDbType.VarChar).Value = _windowsUserNameEMail;
                        cmd.Parameters.Add("@IndActive", SqlDbType.TinyInt).Value = 1;
                        cmd.Parameters.Add("@RecordVersion", SqlDbType.Int).Value = Convert.ToInt32(txt_RecordVersion.Text);
                        //cmd.Parameters.Add("@IdJob", SqlDbType.Int).Value = "DEFAULT";
                        //cmd.Parameters.Add("@IdUser", SqlDbType.Int).Value = "DEFAULT";
                        //cmd.Parameters.Add("@outIdUnique", SqlDbType.Int).Value = "DEFAULT";
                        //cmd.Parameters.Add("@outRecordVersion", SqlDbType.Int).Value = "DEFAULT";
                        //cmd.Parameters.Add("@outInd", SqlDbType.Int).Value = "DEFAULT";
                        //cmd.Parameters.Add("@outMessage", SqlDbType.VarChar).Value = "DEFAULT";

                        cmd.ExecuteNonQuery();
                    

                    // Last Updated Record
                    txt_LastUpdated_IdUnique.Text = txt_IdUnique.Text;
                    txt_LastUpdated_FitsEmpName.Text = txt_FitsEmpName.Text;
                    txt_LastUpdated_FinanceEmpName.Text = txt_FinanceEmpName.Text;

                    // Refresh the Datagrid - the DataGrid_MonikerName
                    // pass in null for the params in order to fire the event
                    btn_RefreshGrid_Click(null, null);



                    // ****************************************
                // TODO:  After Grid Refresh Search the column ID UNIQUE for the value stored in txt_IdUnique.Text which
                //  was just saved via the stored procedure
                // Once the value is found in the DataGrid need to grab the DataGrid Row INdex in order to 
                // Select the ROW and Set the ROW to the SELECTED ROW and set focus to the DataGrid also will need to Scroll the Grid into View.
                    //
                    // ****************************************


                    con.Close();
                
                catch (SqlException ex)
                
                    MessageBox.Show(ex.ToString());                    
                
            
            else
            
                MessageBox.Show("Connection not established to the SQL Server. " + Environment.NewLine + "The SQL Server may be offline or valid credentials are not yet granted.", "SQL Server Connection Error", MessageBoxButton.OK, MessageBoxImage.Error);

                this.Close();
            
           

        this.Cursor = Cursors.Arrow;
    

【问题讨论】:

刷新后还是刷新前需要焦点来表示记录已经更新?? 您好 - 感谢您的快速响应...在网格刷新后我需要它。当网格刷新时,我正在使用新记录集重新填充网格。我刚刚添加了按钮的代码单击 TODO 部分详细说明了刷新后我需要发生的事情 【参考方案1】:

我也为我们系统中的网格使用 DataTable.DefaultView。我还对“MyDataGrid”的 DataGrid 进行了子类化......在 MyDataGrid 上,我有一个自定义方法可以根据其主键强制加载给定的 ID。所以我在网格上有另一个自定义属性,主键列的名称是什么,因为它应该在数据视图中找到,即使它可能不会在网格中直观地显示。

根据您提供的内容,这里是从我的原始代码到您的特定环境的修改...

public void TryGridRefresh()

   int IDToFind = Convert.ToInt32(txt_IdUnique.Text);

   if (IDToFind > -1 && dataGrid1.ItemsSource is DataView )
   
      foreach( DataRowView drv in (DataView)dataGrid1.ItemsSource )
         if ((int)drv["IdUnique"] == IDToFind)
         
            // This is the data row view record you want...
            dataGrid1.SelectedItem = drv;
         
   

所以,就在您致电后

 btn_RefreshGrid_Click(null, null);

然后调用

TryGridRefresh();

我将我的数据网格作为所选值的整个 ROW,而不是每个单元格。因此,您可能需要稍微尝试一下对象引用...一旦找到该行,您也可以尝试使用 dataGrid1.CurrentItem...

希望这将使您更接近最终的解决方案。

【讨论】:

感谢您的回复...我正在查看您的回复和您的代码 sn-p 绑定,以了解如何将其合并为我需要做的事情。很快就会更新 我很难尝试合并您的代码 sn-p : (。请查看我包含的代码,看看是否可以在其中合并 sn-p。谢谢 @RJP,修改后的答案...试试看,让我知道。 非常感谢您的修订……我正在尝试修订。希望很快会更新。谢谢 非常感谢...您的最终修订解决了我的问题。我花了一个多星期的时间搜索谷歌......每次我都不断地来到 ***.com,这只有创建一个帐户并发布问题才有意义。是的,这个社区帮助了我。今晚我可以睡觉了。非常感谢您。我将更新帖子以通过我的调整显示您修改后的解决方案......以帮助其他人。谢谢【参考方案2】:
 public void TryGridRefresh(string IdUniqueToFind, DataGrid MyDataGrid, string MyGridColumnToSearch)
      
        int IDToFind = Convert.ToInt32(IdUniqueToFind);

// this if did not work for me..got errors  
        //if (IDToFind > -1) and (dataGrid_MonikerName.ItemsSource is DataView )
        //
        foreach (DataRowView drv in (DataView)MyDataGrid.ItemsSource)
                       
            if ((int)drv[MyGridColumnToSearch] == IDToFind)
            
                // This is the data row view record you want...
                MyDataGrid.SelectedItem = drv;

                MyDataGrid.ScrollIntoView(drv);
                MyDataGrid.Focus();

                break;
            
        
           

然后在网格刷新调用之后调用该方法 - TryGridRefresh(txt_LastUpdated_IdUnique.Text, dataGrid_MonikerName, gridData_ColumnToSearch);

我也不得不改变 从 CurrentCell.Item 到 SelectedItem 的 datagrid DataRowView 以便捕获所选值的整行而不是每个单元格。

//DataRowView _DataView = dataGrid_MonikerName.CurrentCell.Item as DataRowView; DataRowView _DataView = dataGrid_MonikerName.SelectedItem as DataRowView;

【讨论】:

以上是关于C# WPF DataGrid 在列中搜索值,返回行索引的主要内容,如果未能解决你的问题,请参考以下文章

WPF 格式化输出- IValueConverter接口的使用 datagrid列中的值转换显示

Python Pandas Regex:在列中搜索带有通配符的字符串并返回匹配项[重复]

如果在列中找到重复的单元格值,则返回值

C# WPF Datagrid:从 SelectionChanged 事件中获取值

如何计算某些值在 SQL 表中出现的次数并在列中返回该数字?

Sencha EXT JS datagrid滚动条专门在列上?