数据网格中的CurrentRow在选择其他行之后给出第一行

时间:2019-06-20 16:14:04

标签: c# datagridview contextmenustrip

我有一个C#项目(VS 2017),该项目使用数据网格视图在对象列表中显示数据。使用contextMenuStrip,我希望能够右键单击一行,并能够将其从datagridview和基础数据源中删除。

我在Datagridview的“属性”中设置了contextMenuStrip,其中有一项与处理事件的方法有关。

    private void dgv_Test_MouseDown(object sender, MouseEventArgs e)
    {
        if (e.Button == MouseButtons.Right)
        {
            var hti = dgv_Test.HitTest(e.X, e.Y);

            dgv_Test.ClearSelection();
            dgv_Test.Rows[hti.RowIndex].Selected = true;
        }
    }

    private void cms_DGV_Remove_Click(object sender, EventArgs e)
    {
        MessageBox.Show("Content Menu Clicked on Remove Option");

        PersonModel temp = (PersonModel)dgv_Test.CurrentRow.DataBoundItem;

        string msg = $"The index for the selected Person is {temp.Id}.";
        MessageBox.Show(msg);

    }

我希望这会将当前行发送到右键单击的行。因为CurrentRow停留在第一行,所以这没有发生。如果我先在该行上单击鼠标左键,然后在同一行上单击鼠标右键,它将起作用。

1 个答案:

答案 0 :(得分:0)

您描述的问题来自countdownTimer.delegate = self countdownTimer.setTimer(hours: 0, minutes: 0, seconds: selectedSecs) progressBar.setProgressBar(hours: 0, minutes: 0, seconds: selectedSecs) stopBtn.isEnabled = false stopBtn.alpha = 0.5 view.addSubview(messageLabel) var constraintCenter = NSLayoutConstraint(item: messageLabel, attribute: .centerX, relatedBy: .equal, toItem: self.view, attribute: .centerX, multiplier: 1, constant: 0) self.view.addConstraint(constraintCenter) constraintCenter = NSLayoutConstraint(item: messageLabel, attribute: .centerY, relatedBy: .equal, toItem: self.view, attribute: .centerY, multiplier: 1, constant: 0) self.view.addConstraint(constraintCenter) messageLabel.isHidden = true counterView.isHidden = false } override var preferredStatusBarStyle : UIStatusBarStyle { return .lightContent } //MARK: - Countdown Timer Delegate func countdownTime(time: (hours: String, minutes: String, seconds: String)) { hours.text = time.hours minutes.text = time.minutes seconds.text = time.seconds } func countdownTimerDone() { counterView.isHidden = true messageLabel.isHidden = false seconds.text = String(selectedSecs) countdownTimerDidStart = false stopBtn.isEnabled = false stopBtn.alpha = 0.5 startBtn.setTitle("START",for: .normal) AudioServicesPlaySystemSound(SystemSoundID(1300)) print("countdownTimerDone") } //MARK: - Actions @IBAction func startTimer(_ sender: UIButton) { messageLabel.isHidden = true counterView.isHidden = false stopBtn.isEnabled = true stopBtn.alpha = 1.0 if !countdownTimerDidStart{ countdownTimer.start() progressBar.start() countdownTimerDidStart = true startBtn.setTitle("PAUSE",for: .normal) }else{ countdownTimer.pause() progressBar.pause() countdownTimerDidStart = false startBtn.setTitle("RESUME",for: .normal) } } @IBAction func stopTimer(_ sender: UIButton) { countdownTimer.stop() progressBar.stop() countdownTimerDidStart = false stopBtn.isEnabled = false stopBtn.alpha = 0.5 startBtn.setTitle("START",for: .normal) } 事件。当用户右键单击网格时,即使cms_DGV_Remove_Click方法中的代码将行设置为“ selected”,也不会使光标下方的单元格/行成为网格的CurrentRow.。 。它不一定是“当前”行。网格dgv_Test_MouseDown属性是只读的,您不能直接从代码中对其进行设置。

鉴于此,很明显,从上下文菜单中“相对于网格”获取鼠标坐标将花费一些精力,因为其坐标是全局的。您显然在连接网格CurrentRow事件时注意到了这一点。此事件使捕获相对于网格的鼠标位置变得容易。问题是…您未保存此信息。在上下文菜单触发时,该信息已丢失。

解决方案:将MouseDown信息设为全局。然后,在每次用户右键单击网格时进行设置。设置了此全局变量后,当上下文菜单触发时,它将知道光标位于哪一行。

DataGridView.HitTest

似乎发布的代码实际上并未删除该行,但是下面是上下文菜单“删除”事件的外观……

以下内容应适用于非数据绑定网格以及具有数据绑定DataGridView.HitTestInfo HT_Info; // <- Global variable private void dgv_Test_MouseDown(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Right) { HT_Info = dgv_Test.HitTest(e.X, e.Y); if (HT_Info.RowIndex >= 0) { dgv_Test.ClearSelection(); dgv_Test.Rows[HT_Info.RowIndex].Selected = true; } } } 的网格

DataTable.

如果您使用的是private void cms_DGV_Remove_Click(object sender, EventArgs e) { if (HT_Info.RowIndex >= 0) { dgv_Test.Rows.Remove(dgv_Test.Rows[HT_Info.RowIndex]); } } ,则删除方法可能如下所示...

List<T>

我猜这是您要寻找的行为。用户右键单击网格,选中光标下方的行,并弹出上下文菜单“删除”。用户可以“选择”删除以删除该行,也可以从上下文菜单中单击以取消删除。

希望如此。