簡體   English   中英

RadioButton Click 事件在啟動時錯誤地觸發

[英]RadioButton Click event erroneously fires on startup

編輯:這是一個與本提議副本中涵蓋的問題不同的問題。 這個問題解決了一個不同的問題,那里的答案都不適用於我的情況。 我的單選按鈕從一開始就被檢查了,因為它應該是。 它(或者更確切地說是它的組的成員)是在加載事件處理程序期間使用保存的屬性設置的。 另外,如下所述,我麻煩的單選按鈕不是選項卡順序中的第一個。

我剛開始在 WinForms 應用程序上遇到問題,我的任務是重構。

窗體的 Load 事件處理程序完成一段時間后,一個特定單選按鈕的 Click 事件會自動觸發。 我不明白為什么,它打亂了程序的預期流程。

我在單擊處理程序的開頭放置了一個斷點並檢查了調用堆棧,但麻煩的調用總是來自外部代碼,最后兩行是 RadioButton.OnEnter,然后是 Control.OnClick

谷歌搜索出現了這個 SE answer ,但這與我的情況不太相符。 有問題的單選按鈕在選項卡順序中相當靠后,所有控件都是在 VS 設計器中添加的,而不是通過代碼添加的,加載處理程序在完成之前將焦點設置到另一個控件。 在 Load 處理程序的末尾和錯誤的 Click 之間沒有遇到對單選按鈕引用(使用太多斷點進行驗證)。

有誰知道還有什么可能導致在啟動時自動單擊控件?

編輯這是單選按鈕 (mVmOff) 的設計器代碼及其所在的嵌套組框:

            // 
            // mVmGroup (6th in tab order)
            // 
            this.mVmGroup.Controls.Add(this.milliVmGroup);
            this.mVmGroup.Controls.Add(this.mVRLabel);
            this.mVmGroup.Controls.Add(this.mVmLabel);
            this.mVmGroup.Controls.Add(this.mVRCombo);
            this.mVmGroup.Controls.Add(this.mVm);
            this.mVmGroup.Font = new System.Drawing.Font("Verdana", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.mVmGroup.ForeColor = System.Drawing.Color.Black;
            this.mVmGroup.Location = new System.Drawing.Point(200, 295);
            this.mVmGroup.Name = "mVmGroup";
            this.mVmGroup.Size = new System.Drawing.Size(169, 140);
            this.mVmGroup.TabIndex = 6;
            this.mVmGroup.TabStop = false;
            this.mVmGroup.Text = "mV Meter";
            this.toolTip.SetToolTip(this.mVmGroup, "This is the Milli Voltmeter\'s matrix.");
            // 
            // milliVmGroup (6.4 in tab order)
            // 
            this.milliVmGroup.Controls.Add(this.mVmOS);
            this.milliVmGroup.Controls.Add(this.mVmOff);
            this.milliVmGroup.Controls.Add(this.mVmIS);
            this.milliVmGroup.Font = new System.Drawing.Font("Verdana", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.milliVmGroup.ForeColor = System.Drawing.Color.RoyalBlue;
            this.milliVmGroup.Location = new System.Drawing.Point(8, 63);
            this.milliVmGroup.Name = "milliVmGroup";
            this.milliVmGroup.Size = new System.Drawing.Size(152, 71);
            this.milliVmGroup.TabIndex = 4;
            this.milliVmGroup.TabStop = false;
            this.milliVmGroup.Text = "Matrix";
            // 
            // mVmOff (6.4.2 in tab order)
            // 
            this.mVmOff.AutoSize = true;
            this.mVmOff.Checked = true;
            this.mVmOff.Font = new System.Drawing.Font("Verdana", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.mVmOff.Location = new System.Drawing.Point(5, 49);
            this.mVmOff.Name = "mVmOff";
            this.mVmOff.Size = new System.Drawing.Size(42, 17);
            this.mVmOff.TabIndex = 2;
            this.mVmOff.TabStop = true;
            this.mVmOff.Text = "Off";
            this.toolTip.SetToolTip(this.mVmOff, "Click to disconnect the Milli Voltmeter. \r\nDisconnects K29, K8, and K30. \r\nConnec" +
        "ts K3 and K11. \r\n \r\nNote: Normaly checked.");
            this.mVmOff.UseVisualStyleBackColor = true;
            this.mVmOff.Click += new System.EventHandler(this.MVmOff_Click);

以及表格該部分的屏幕截圖: mV Meter 組合框

如果有幫助,在錯誤點擊發生的斷點處,單選按鈕是唯一繪制在窗體上的控件。

通常,您應該依賴 CheckedChange 並僅在發生點擊時才使用 Click。

但我會回答你的問題:

有誰知道還有什么可能導致在啟動時自動單擊控件?

您的 RadioButton 按預期聚焦。 然后引發 Click 事件是 RadioButton 的OnEnter方法中存在的邏輯錯誤。 當您使用箭頭鍵輸入控件時,它會嘗試引發 OnClick,但它無法以正確的方式執行此操作,例如,即使焦點在沒有箭頭鍵的情況下自動移動到控件,它也會引發 Click 事件。

您可以通過覆蓋 OnEnter 在輸入控件時禁用引發 Click 事件:

using System;
using System.Windows.Forms;
public class MyRadioButton : RadioButton
{
    protected override void OnEnter(EventArgs e)
    {
        RaiseOnEnter(e);
    }
    private void RaiseOnEnter(EventArgs e)
    {
        var EventEvent = typeof(Control).GetField("EventEnter",
        System.Reflection.BindingFlags.NonPublic |
        System.Reflection.BindingFlags.Static).GetValue(null);
        EventHandler handler = (EventHandler)Events[EventEvent];
        handler?.Invoke(this, e);
    }
}

關於 .NET 5 和 6 的注意事項

即使在.NET 5 和 6 RadioButton中也有同樣的問題; 如果您想對這些版本使用上述解決方法,請確保您獲得s_enterEvent字段。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM