我有一个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停留在第一行,所以这没有发生。如果我先在该行上单击鼠标左键,然后在同一行上单击鼠标右键,它将起作用。
答案 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>
我猜这是您要寻找的行为。用户右键单击网格,选中光标下方的行,并弹出上下文菜单“删除”。用户可以“选择”删除以删除该行,也可以从上下文菜单中单击以取消删除。
希望如此。