0

SelecterControl透明な画像を持つコントロールを含む (背景に透明な画像を持つ) ユーザー コントロールを定義しますRoll

フロントコントロールを に移動したいSelecterControl

それをすると透明部分がSelecterControlクリアされません。

ここに画像の説明を入力

私の完全なコードは以下のとおりです。

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);
    }
}
}

この問題の原因は何ですか? 助けてくれてありがとう。

4

1 に答える 1

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

それがあなたのコードの中心的な問題です。「ロール」コントロールが小さすぎます。CreateParams プロパティで WS_EX_TRANSPARENT フラグを使用すると、コントロールの背後にあるウィンドウが常に最初に描画されるように Windows に要求します。「ロール」コントロールの背景ピクセルを設定して、その上に独自のものをペイントできるようにします。

問題は、ロール コントロールが小さすぎて、移動した後、以前に描画された浮遊ピクセルをオーバーラップするのに十分な大きさではないことです。それらはもはやロール コントロール ウィンドウ内にはありません。そのため、それらはそこにとどまり、目に見えるにじみ効果を生み出します。

これを回避する唯一の方法は、ロール コントロールを大きくして、常にそれらのピクセルをキャッチすることです。現実的には、スライダーの範囲と同じ大きさです。問題は、「ロール」を独自のコントロールにする利点がすべて失われることです。ヒット テストなどは複雑になります。ユーザーがクリックしたことを知るには、サムがどこにあるかを知る必要があります。

スライダーとつまみの両方を描画する1 つのコントロールを作成することもできます。必要なコードはまったく同じです。また、使用するシステム リソースが少なくなるため、より効率的になります。ウィンドウは高価なオブジェクトです。

于 2012-08-05T17:02:39.137 に答える