2010-12-10 93 views
-4

我想創建一個組合自定義控件,其中包含將由某些客戶端表單使用的跟蹤欄和其他控件。我需要公開一些事件,如MouseDownMouseUp以檢測拖動的開始和拖動的結束。奇怪的是,MouseDown是好的,但不是MouseUp。下面的代碼演示了它。這是.NET Framework或trackbar中的錯誤嗎?如果不是,我應該怎麼做呢?爲什麼我的自定義用戶控件不會引發鼠標事件?

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Drawing; 
using System.Data; 
using System.Text; 
using System.Windows.Forms; 

namespace MyTrackbar 
{ 

    public partial class UserControl1 : UserControl 
    { 
     public delegate void StartDragHandler(); 
     public delegate void EndDragHandler(); 

     [Category("Action")] 
     [Description("Fires when user starts to drag.")] 
     public event StartDragHandler StartDrag; 
     [Category("Action")] 
     [Description("Fires when user ends to drag.")] 
     public event EndDragHandler EndDrag; 

     public UserControl1() 
     { 
      InitializeComponent(); 
     } 

     private void trackBar1_MouseDown(object sender, MouseEventArgs e) 
     { 
      textBox1.BackColor = Color.Red; 
      if (StartDrag != null) { 
       StartDrag(); 
      } 

     } 

     private void trackBar1_MouseUp(object sender, MouseEventArgs e) 
     { 
      textBox1.BackColor = Color.White; 
      if (EndDrag != null) { 
       EndDrag(); 
      } 
     } 
    } 
} 



using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Text; 
using System.Windows.Forms; 

namespace TestMyTrackBar 
{ 
    public partial class Form1 : Form 
    { 
     public Form1() 
     { 
      InitializeComponent(); 
     } 

     private void userControl11_StartDrag() 
     { 
      // Work 
      textBox1.BackColor = Color.Red; 
     } 

     private void userControl11_MouseUp(object sender, MouseEventArgs e) 
     { 
      // Doesn't work !!!!!!!!!!!! 
      textBox1.BackColor = Color.White; 
     } 
    } 
} 

更新:對於誰需要檢查InitializeComponent人,即使我沒有修改它:

對於自定義控制:

namespace MyTrackbar 
{ 
    partial class UserControl1 
    { 
     /// <summary> 
     /// Required designer variable. 
     /// </summary> 
     private System.ComponentModel.IContainer components = null; 

     /// <summary> 
     /// Clean up any resources being used. 
     /// </summary> 
     /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> 
     protected override void Dispose(bool disposing) 
     { 
      if (disposing && (components != null)) 
      { 
       components.Dispose(); 
      } 
      base.Dispose(disposing); 
     } 

     #region Component Designer generated code 

     /// <summary> 
     /// Required method for Designer support - do not modify 
     /// the contents of this method with the code editor. 
     /// </summary> 
     private void InitializeComponent() 
     { 
      this.trackBar1 = new System.Windows.Forms.TrackBar(); 
      this.textBox1 = new System.Windows.Forms.TextBox(); 
      ((System.ComponentModel.ISupportInitialize)(this.trackBar1)).BeginInit(); 
      this.SuspendLayout(); 
      // 
      // trackBar1 
      // 
      this.trackBar1.Location = new System.Drawing.Point(21, 17); 
      this.trackBar1.Name = "trackBar1"; 
      this.trackBar1.Size = new System.Drawing.Size(356, 45); 
      this.trackBar1.TabIndex = 0; 
      this.trackBar1.MouseDown += new System.Windows.Forms.MouseEventHandler(this.trackBar1_MouseDown); 
      this.trackBar1.MouseUp += new System.Windows.Forms.MouseEventHandler(this.trackBar1_MouseUp); 
      // 
      // textBox1 
      // 
      this.textBox1.Location = new System.Drawing.Point(31, 68); 
      this.textBox1.Name = "textBox1"; 
      this.textBox1.Size = new System.Drawing.Size(338, 20); 
      this.textBox1.TabIndex = 1; 
      // 
      // UserControl1 
      // 
      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 
      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 
      this.Controls.Add(this.textBox1); 
      this.Controls.Add(this.trackBar1); 
      this.Name = "UserControl1"; 
      this.Size = new System.Drawing.Size(400, 150); 
      ((System.ComponentModel.ISupportInitialize)(this.trackBar1)).EndInit(); 
      this.ResumeLayout(false); 
      this.PerformLayout(); 

     } 

     #endregion 

     private System.Windows.Forms.TrackBar trackBar1; 
     private System.Windows.Forms.TextBox textBox1; 
    } 
} 

對於WinForm的客戶端:

namespace TestMyTrackBar 
{ 
    partial class Form1 
    { 
     /// <summary> 
     /// Required designer variable. 
     /// </summary> 
     private System.ComponentModel.IContainer components = null; 

     /// <summary> 
     /// Clean up any resources being used. 
     /// </summary> 
     /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> 
     protected override void Dispose(bool disposing) 
     { 
      if (disposing && (components != null)) 
      { 
       components.Dispose(); 
      } 
      base.Dispose(disposing); 
     } 

     #region Windows Form Designer generated code 

     /// <summary> 
     /// Required method for Designer support - do not modify 
     /// the contents of this method with the code editor. 
     /// </summary> 
     private void InitializeComponent() 
     { 
      this.userControl11 = new MyTrackbar.UserControl1(); 
      this.textBox1 = new System.Windows.Forms.TextBox(); 
      this.SuspendLayout(); 
      // 
      // userControl11 
      // 
      this.userControl11.Location = new System.Drawing.Point(13, 39); 
      this.userControl11.Name = "userControl11"; 
      this.userControl11.Size = new System.Drawing.Size(400, 114); 
      this.userControl11.TabIndex = 0; 
      this.userControl11.StartDrag += new MyTrackbar.UserControl1.StartDragHandler(this.userControl11_StartDrag); 
      this.userControl11.MouseUp += new System.Windows.Forms.MouseEventHandler(this.userControl11_MouseUp); 
      // 
      // textBox1 
      // 
      this.textBox1.Location = new System.Drawing.Point(45, 160); 
      this.textBox1.Name = "textBox1"; 
      this.textBox1.Size = new System.Drawing.Size(336, 20); 
      this.textBox1.TabIndex = 1; 
      // 
      // Form1 
      // 
      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 
      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 
      this.ClientSize = new System.Drawing.Size(457, 231); 
      this.Controls.Add(this.textBox1); 
      this.Controls.Add(this.userControl11); 
      this.Name = "Form1"; 
      this.Text = "Form1"; 
      this.ResumeLayout(false); 
      this.PerformLayout(); 

     } 

     #endregion 

     private MyTrackbar.UserControl1 userControl11; 
     private System.Windows.Forms.TextBox textBox1; 
    } 
} 
+0

你實際上是在使用'TrackBar'控件,還是建立了自己的自定義滑塊? – 2010-12-10 16:58:57

+1

你說得對,我只是意識到,當我將軌跡欄嵌入到自定義控件中時,它不起作用。 – user310291 2010-12-11 10:57:56

+0

@ user310291如果它不起作用,它不能成爲框架錯誤。如果是這樣,.NET框架應該比它的SLOC計數有更多的錯誤! – Luca 2010-12-11 18:08:40

回答

2
private void userControl11_MouseUp(object sender, MouseEventArgs e) 
    { 
     // Doesn't work !!!!!!!!!!!! 
     textBox1.BackColor = Color.White; 
    } 

Y你應該使用EndDrag事件,而不是MouseUp。

+0

抱歉,我太累了,那一天,我沒有看到我明顯的錯誤:) – user310291 2010-12-14 23:04:37

1

目前還不清楚真正的問題,因爲InitializeComponent的實現完全從示例中丟失。

所以,我的回答是基於以下斷言:

  • UserControl1.trackBar1的TrackBar,* trackBar1_MouseDown *是UserControl1.trackBar1.MouseDown的subsciber,* trackBar1_MouseUp *是UserControl1.trackBar1.MouseUp
  • Form1.userControl11的subsciber是的UserControl1,* userControl11_StartDrag()*是Form1.userControl11.StartDrag事件的訂戶,* userControl11_MouseUp *是Form1.userControl11.MouseUp事件

這是正確的, 「不工作」 的用戶。可能(如果是的話,你應該確認)事件Form1.userControl11.MouseUp永遠不會被引發。 Infact Form1.userControl11.MouseUp and UserControl1.trackBar1.MouseUp不一樣; INFACT 的UserControl1類暴露EndDrag事件當其嵌入控制trackBar1引發的MouseUp事件。

因此,解決方案是訂閱UserControl1.EndDrag事件,而不是鼠標向上(如Hans Passant所述),以反映正確的行爲(我認爲)。

+0

沒有什麼特別的InitializeComponent這就是爲什麼我沒有發佈它。現在,我可以發佈它,如果你想確保沒有錯。 – user310291 2010-12-11 18:50:17

+0

「解決方案是訂閱EndDrag事件」:這是不可能的,因爲Trackbar控件不存在此事件,或者我錯過了什麼? – user310291 2010-12-11 18:56:29

+0

EndDrag事件在UserControl1類中聲明,它不是一個TrackBar。然而,重讀漢斯帕斯坦的回答和評論,我的回答完全一樣。 – Luca 2010-12-11 22:43:02

3

在開始之前,我想澄清一下answer provided by Hans Passant已經解釋了我正要做的事情。所以,如果你覺得這有幫助,你應該提出他的答案。

但是,從評論交流看來,你並不完全明白他想說什麼。也許我可以更好地解釋它,也許如果你明白你在代碼中改變了什麼,如果瞭解發生了什麼,你會更容易。

讓我們從評估當前情況開始:當用戶開始拖動軌跡條時,屬於userControl11的文本框會正確更改顏色。但是,在完成拖動軌跡條後,作爲Form1一部分的第二個文本框不會變回白色。

您的用戶控件已經引發了兩個自定義事件StartDragEndDrag,其中的名稱顯然表示當前狀態。在Form1中,您正在處理用戶控件的StartDrag事件並將第二個文本框的顏色更改爲紅色。但是,不是處理EndDrag事件以將顏色更改爲白色,而是處理MouseUp事件。這就是爲什麼它不起作用,漢斯的回答是想告訴你什麼。 相反,你的窗體的代碼看起來應該是這樣:

public partial class Form1 : Form 
{ 
    public Form1() 
    { 
     InitializeComponent(); 

     this.userControl11.EndDrag += new MyTrackbar.UserControl1.EndDragHandler(this.userControl11_EndDrag); 
    } 

    private void userControl11_StartDrag() 
    { 
     // Works 
     textBox1.BackColor = Color.Red; 
    } 

    private void userControl11_EndDrag() 
    { 
     // Now also works! 
     textBox1.BackColor = Color.White; 
    } 
} 

你已經明白你需要處理你提的定製StartDrag事件,因此它似乎很簡單,你最好也需要來處理事件以達到預期的效果。

但是,你可能會問,「爲什麼MouseUp事件在用戶控件裏面工作,但是不是工作在窗體裏面?!?」我認爲這是你試圖爭論的是.NET Framework中的一個錯誤。 (提示:這是不太可能,任何人都會發現在框架真正的bug比我們中的一個困惑爲什麼我們看到,我們的行爲,或者只是缺少明顯的東西。)

原因是因爲在用戶控件內部,您正在處理trackbar控件(trackBar1)引發的MouseUp事件。 但該事件不會向上傳播。僅僅因爲trackbar控件引發了MouseUp事件,而不是意味着包含它的用戶控件引發同一事件。您似乎已經知道,關於MouseDown事件,與MouseUp事件完全相同。

不需要向微軟提交錯誤報告,也不需要任何人讓自己的感受受到傷害。

相關問題