2012-08-05 138 views
0

我定義了SelecterControl用戶控件(透明圖像在背景中),其中包含透明圖像的Roll控件。在另一個透明圖像上移動透明圖像

我想通過SelecterControl移動前端控件。

什麼時候這樣做,透明面積SelecterControl不明確。

enter image description here

我的完整代碼如下:

using System; 
using System.Drawing; 
using System.Windows.Forms; 
using System.IO; 

namespace TestControl 
{ 
public partial class SelecterControl : UserControl 
{ 
    private Roll roll; 

    public SelecterControl() 
    { 
     InitializeComponent(); 
     BackgroundImage = Image.FromStream(new MemoryStream(Convert.FromBase64String("iVBORw0KGgoAAAANSUhEUgAAAPsAAAAWCAYAAAAGqOr6AAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3AgFDRwUWvPXdAAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAACxklEQVR42u3cv0sbYRwG8McgucnXpiBCThyCpUMqGa4RobhlKDjKBSLt0EU7tbQQmv4FjQj94aRZOhSSkiKdQqFNJxGkIUOKGQohFMmlBEHrOSVQ0yE5aYJW7jyVO54PhCwX3vDePfd+733vbgBn88G6fRCRWReSuYEzGlQABM7RaJ6BJzId9Mg5Al8FUDwpd4MnNXZj6Lby+uH7pPB7Fb3egvB7TbWm11uYXZ5Y5H4jMicXr+xZyZvwe6HXW9X7b2ZSe61fgW7gq/+Gvj/svsx8OSlkaWEsPITxaYFhWTL9hz8lqtxrRBbdeTRm+jcHWhM7W3rg3eON5PfPP/PPSxGjSjge5Qf7ziprwu9VrTRGRFdnWJYwOTeCybkRCL83kimUfbF0MNUNehEAPMbGG692njHoRO6oDMbCQ8qLUF5FZ97N1z+yJ2/Njdg90eBzWD9d46HS4ze7wJm6WY7gCfLdwOcHu6P6mpAlS9fn/6F0v500Gz/Dw6THBrvAuWW9kCVk5stqLB2sAvAZI7s6Pi1sbezpzbdqWJlShb0nELpc99gFzjU+LaBrTQXp3jLe9nI7rEzhbjJgd7VA5GoXuZLlATrrdAwlkftKeb3e6g07EbmfBwCE34sDrcneIHKRA61p3P3ac1PNvt3X7YXiNyABcIKO6Mrt5+KVzqpYKdtIlrKN9tGfI1s+uXilDWABzltnJ7pSuXjFthyWso12Zr78xcihBwBC0dGErjVZyhO5qITXtSZi6WDCKOOPJ+iELC1ur++yl4hcYHt9F7XC4RI6T76hJ+yh6GhKyFJqc6XGniJysM2VGvR660MsHVzCaY+4hqKji6Vso7i5UlsTsmT5EVdjUoDdTnR5ZfvOlo5a4RAAlmaXJxL925z6pppStpHVtaZ6jpdXXGfgiczJxSttqy+vAJD/uPo1+vLHA+aOiIjI9f4CBEpvEw5QVnUAAAAASUVORK5CYII="))); 
     SetStyle(ControlStyles.SupportsTransparentBackColor, true); 
     BackColor = Color.Transparent; 
    } 

    protected override CreateParams CreateParams 
    { 
     get 
     { 
      CreateParams cp = base.CreateParams; 
      cp.ExStyle |= 0x20; 
      return cp; 
     } 
    } 

    protected override void OnPaintBackground(PaintEventArgs e) 
    { 
    } 

    protected override void OnPaint(PaintEventArgs e) 
    { 
     if (BackgroundImage != null) 
      e.Graphics.DrawImage(BackgroundImage, e.ClipRectangle, e.ClipRectangle, GraphicsUnit.Pixel); 
    } 

    #region Roll Horizontal Movement 

    int strtX; 

    private void roll_MouseDown(object sender, MouseEventArgs e) 
    { 
     strtX = e.X; 
    } 

    private void roll_MouseMove(object sender, MouseEventArgs e) 
    { 
     if (e.Button == System.Windows.Forms.MouseButtons.Left) 
      roll.Left += e.X - strtX; 
    } 

    #endregion 

    #region Designer generated code 

    private System.ComponentModel.IContainer components = null; 

    protected override void Dispose(bool disposing) 
    { 
     if (disposing && (components != null)) 
     { 
      components.Dispose(); 
     } 
     base.Dispose(disposing); 
    } 

    private void InitializeComponent() 
    { 
     System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(SelecterControl)); 
     this.roll = new MapControl.Roll(); 
     this.SuspendLayout(); 
     // 
     // roll 
     // 
     this.roll.BackColor = System.Drawing.Color.Transparent; 
     //this.roll.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("roll.BackgroundImage"))); 
     this.roll.Location = new System.Drawing.Point(87, 1); 
     this.roll.Name = "roll"; 
     this.roll.Size = new System.Drawing.Size(13, 18); 
     this.roll.TabIndex = 0; 
     this.roll.MouseDown += new System.Windows.Forms.MouseEventHandler(this.roll_MouseDown); 
     this.roll.MouseMove += new System.Windows.Forms.MouseEventHandler(this.roll_MouseMove); 
     // 
     // SelecterControl 
     // 
     this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 
     this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 
     //this.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("$this.BackgroundImage"))); 
     this.Controls.Add(this.roll); 
     this.Name = "SelecterControl"; 
     this.Size = new System.Drawing.Size(251, 22); 
     this.ResumeLayout(false); 

    } 

    #endregion 
} 


class Roll : Control 
{ 
    public Roll() 
    { 
     BackgroundImage = Image.FromStream(new MemoryStream(Convert.FromBase64String("iVBORw0KGgoAAAANSUhEUgAAAA0AAAASCAYAAACAa1QyAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3AgFDR0RM4ISugAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAAA5UlEQVQoz2NkQAWCUMyARMPAexjNAhORjTul5GEhd5cBC1jc4h/249nJ9zCNjAwMDAwaufeVbDU57zIwMLyfnCKKYkPunNcwjek/np28x8DAcI+JgYGBAVnDozd/4BoevfnDMDlFlIGBgYEhtmbjTJizmWAKYBrkROAuZpATYUHRCANM2PygU/iIQafwEQMuwMRABhjVRIkmFmyCV/rl8Ol5z4SUxt7DUgByMpITYYGnP1iChWkSYmBgEIRpRE5GMA3LJ2abQDW9Z4QpSJ32QpCBgeEdNvesnt+p/OF0/3ukPEU6AADyU1AuXNEg+gAAAABJRU5ErkJggg=="))); 
     SetStyle(ControlStyles.SupportsTransparentBackColor, true); 
     BackColor = Color.Transparent; 
    } 

    protected override CreateParams CreateParams 
    { 
     get 
     { 
      CreateParams cp = base.CreateParams; 
      cp.ExStyle |= 0x20; 
      return cp; 
     } 
    } 

    protected override void OnPaintBackground(PaintEventArgs e) 
    { 
    } 

    protected override void OnPaint(PaintEventArgs e) 
    { 
     if (BackgroundImage != null) 
      e.Graphics.DrawImage(BackgroundImage, e.ClipRectangle, e.ClipRectangle, GraphicsUnit.Pixel); 
    } 
} 
} 

是什麼這個問題的原因是什麼? 感謝您的幫助。

回答

1
this.roll.Size = new System.Drawing.Size(13, 18); 

這是您的代碼中的核心問題,「滾動」控件太小。在CreateParams屬性中使用WS_EX_TRANSPARENT標誌時,要求Windows確保控件後面的窗口總是先繪製。它爲您的「滾動」控件設置背景像素,因此它可以在其上繪製自己的內容。

問題是,你的滾動控制是如此之小,以至於在你移動它之後,它的大小不足以覆蓋之前繪製的雜散像素。它們不再位於側傾控制窗口內。所以他們會留在那裏,產生你看到的拖影效果。

避免這種情況的唯一方法是使您的側傾控制更大,以便始終抓住這些像素。實際上,與滑塊的範圍一樣大。問題是,你現在失去了「滾動」自己的控制權的所有好處。像命中測試這樣的事情變得複雜,你需要知道拇指在哪裏以知道用戶點擊了它。

您不妨創建一個一個控件,它同時繪製滑塊和拇指。所需的代碼完全相同。而且由於使用較少的系統資源,Windows將會更加高效,而Windows則是昂貴的對象。

+0

感謝解釋問題,它很有用。我將捲尺寸更改爲(80,100),但不更改。還可以爲「SelecterControl」添加點擊事件並通過單擊更改卷位置,但不要更改。刪除'roll'控件並在繪畫事件上繪製它,但背景的透明部分仍是塗抹。嘗試使父窗體無效以清除背景,但是進入無限循環。 – g2sea 2012-08-05 19:57:05