C\#PictureBox 를 사용 하여 그림 단추 컨트롤 을 실현 하 는 예제 절차

머리말
우 리 는 때때로 프로그램의 폴 더 에서 아이콘 을 볼 수 있 는데,이 아이콘 들 은 마침 단추 의 배경 그림 으로 사용 된다.마우스 포인터 가 서로 다른 상태 에 있 을 때'들 어가 기 버튼','왼쪽 버튼 누 르 기','놓 기','떠 나 기 버튼'이 있 으 면 단추 의 배경 그림 도 바 뀌 고 있다.이 사진 들 은 대체로 다음 과 같다.



전문 은 첫 번 째 그림 소 재 를 예 로 들 면 이 그림 은 4 단(아래 그림 참조)으로 나 눌 수 있 는데 마침 마우스 포인터 가 컨트롤 을 조작 할 때 각각 다른 상 태 를 나타 내 고 왼쪽 에서 오른쪽으로'초기 상태'(기본 표시 배경),'포인터 가 버튼 영역 에 들 어가 거나 마우스 왼쪽 단 추 를 누 르 면 풀 리 지 않 음','마우스 왼쪽 단 추 를 누 르 면 움 직 이지 않 음'으로 나 타 났 다."마우스 포인터 가 단추 영역 을 떠 납 니 다"

자체 적 으로 이 사진 소 재 는 매우 교묘 하 게 디자인 되 었 는데 그 사 이 즈 는 164*41 이기 때문에 한 단락 의 사 이 즈 는 딱 41*41 이다.
코드 를 붙 이기 전에 먼저 효 과 를 보십시오.

컴 파일 환경 및 설명
  • Microsoft Visual Studio 2010
  • C# .Net Framework 4.0
  • 4.567917.이 그림 단추 의 기능 을 실현 하 는 동시에 일부 코드 를 추가 하여 그림 단추 가 마우스 포인터 와 상호작용 할 때 반 짝 이 는 것 을 방지 했다.
    이미지 소재 분할
    분명히 상기 사진 소 재 는 4 단 으로 나 누 어 마우스 포인터 로 서 의 서로 다른 상태 로 나 누 어 분할 을 실현 하 는 방향 은?
    그림 을 Image 대상 으로 변환 합 니 다
  • 이 이미지 대상 을 복제(컨트롤 배경 을 직접 조작 하여 문 제 를 일 으 키 는 것 을 방지)
  • 비트 맵 의 용기 List 를 만 들 고 분 단 된 4 개의 그림 대상 을 저장 합 니 다
  • 4.567917.사각형 구역 Rectangle 구조 체 를 정의 합 니 다.이 는 전체 그림 소재 중의 어느 부분 을 취해 야 하 는 지 를 나타 내 고 for 순환 으로 이 4 단 그림 의 왼쪽 상단 좌표(즉 시작 좌표),너비,높이 를 계산 한 다음 에 값 에 대응 하 는 것 을 Rectangle 구조 체 중의 속성 에 부여 합 니 다4.567917.이전 Rectangle 구조 체 가 대응 하 는 영역 아래 그림 블록 을 복제 하고 3 단계 에서 언급 한 List 용기 에 추가 하고 이 용 기 를 되 돌려 줍 니 다.
    여기 서 함 수 를 정의 할 수 있다. ImageSplit ,코드 는 다음 과 같다.
    
    ///
    
    ///       ,            
    ///
    ///       
    ///       ,   1 
    ///         
    private List ImageSplit(int ImageWidth, int SegmentsNum = 1)
    {
    //             
    List SplitedImage = new List();
    //         
    Bitmap SrcBmp = new Bitmap(this.Image);
    //          ARGB 
    PixelFormat ReslouteFormat = PixelFormat.Format32bppArgb;
    //       
    Rectangle SplitAreaRec = new Rectangle();
    //          
    if (ImageWidth <= 0 || SegmentsNum <= 0)
    return SplitedImage;
    else
    {
    //             
    //   0( )   SegmentsNum - 1( )
    for (int i = 0; i < SegmentsNum; i++)
    {
    /*
    *           4    ,         41 * 41
    *                 (     )
    * (0, 0)
    * (41, 0)
    * (82, 0)
    * (123, 0)
    * Y      0
    *
    *           :ImageWidth / SegmentsNum (   /      )
    *    X = i * (ImageWidth / SegmentsNum)
    */
    SplitAreaRec.X = 0 + i * (ImageWidth / SegmentsNum);
    SplitAreaRec.Y = 0;
    //        ,          
    SplitAreaRec.Width = ImageWidth / SegmentsNum;
    SplitAreaRec.Height = ImageWidth / SegmentsNum;
    //         ,       
    Bitmap SplitedBmp = SrcBmp.Clone(SplitAreaRec, ReslouteFormat);
    //      
    SplitedImage.Add(SplitedBmp);
    }
    GC.Collect();
    return SplitedImage;
    }
    }
    
    이벤트 처리
    이 그림 단추 컨트롤 은 다음 과 같은 몇 가지 사건 을 처리 해 야 합 니 다.
    OnPaint(컨트롤 그리 기 이벤트)
  • OnMouseEnter(마우스 포인터 가 컨트롤 영역 에 들 어가 면 이벤트 가 발생 합 니 다)
  • OnMouse Down(마우스 왼쪽 단 추 를 눌 러)
  • OnMouseUp  (마우스 우 클릭 으로 놓 기)
  • OnMouse Leave(마우스 포인터 가 컨트롤 영역 을 벗 어 나 는 것)
  • OnPaint 이벤트
    우선 사용자 정의 컨트롤 클래스 에서 개인 대상,버퍼 를 정의 합 니 다. Image 대상(처음에 공백 도형)과 대응 하 는 버퍼 Graphics 대상(빈 그림 에 그림 그리 기),반 짝 임 을 줄 이기 위해 서 입 니 다.
    
    Image buffImg;
    Graphics buffImgG;
    구체 적 인 코드 는 다음 과 같다.
    
    protected override void OnPaint(PaintEventArgs pe)
    {
    base.OnPaint(pe);
    //      
    buffImg = new Bitmap(Width,Height);
    //          Graphics  
    buffImgG = Graphics.FromImage(buffImg);
    //      ,         
    buffImgG.Clear(this.BackColor);
    
    //     
    pe.Graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
    //   
    pe.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
    
    //    
    GraphicsPath gp = new GraphicsPath();
    //           
    //      
    Rectangle limitedRec = new Rectangle();
    Point startDrawingPoint = new Point(0, 0);
    limitedRec.Location = startDrawingPoint;
    limitedRec.Size = new Size(Width - 1, Height - 1);
    
    if (IsWeightWidthEqual)
    {
    int fixedWidth = Width - 1;
    Height = Width;
    Width = Height;
    limitedRec.Size = new Size(fixedWidth, fixedWidth);
    }
    //                    
    //       
    gp.AddEllipse(limitedRec);
    //      
    Region rg = new Region(gp);
    this.Region = rg;
    //    
    rg.Dispose();
    gp.Dispose();
    }
    마우스 대화 이벤트
    위 5 개 사건 제외 OnPaint 이외에 나머지 는 모두 마우스 상호작용 이벤트 이다
    본 고 는 컨트롤 이 반 짝 이 는 문 제 를 처 리 했 기 때문에 이 이벤트 함 수 를 다시 쓸 때 하 나 를 추가 해 야 합 니 다. BufferedGraphics 대상 을 할당 하고 마지막 으로 렌 더 링(Render)을 사용 하여 현재 컨트롤 에 그 려 진 그림 을 보 여 줍 니 다. Graphics 캔버스(/장치)대상(중간 버퍼 를 추가 하여 그림 을 완성 한 후 컨트롤 배경 에 직접 덮어 쓰 는 것 과 같 습 니 다)
    다음은 OnMouse Enter 이벤트 의 코드 입 니 다. 
    
    //1.    
    protected override void OnMouseEnter(EventArgs e)
    {
    base.OnMouseEnter(e);
    using (Graphics g = Graphics.FromHwnd(this.Handle))
    {
    //      
    g.InterpolationMode = InterpolationMode.HighQualityBicubic;
    //    
    g.SmoothingMode = SmoothingMode.AntiAlias;
    //             
    buffImgG.Clear(this.BackColor);
    //              2    
    buffImgG.DrawImageUnscaledAndClipped(SplitedImage[1], ClientRectangle);
    //         buffImgG    Graphics,           
    BufferedGraphics buff = BufferedGraphicsManager.Current.Allocate(buffImgG, ClientRectangle);
    // BufferedGraphics      ,             
    //       DrawImageUnscaledAndClipped
    buff.Graphics.DrawImageUnscaledAndClipped(buffImg, ClientRectangle);
    //             Graphics  
    buff.Render(g);
    }
    }
    다른 마우스 인 터 랙 션 사건 은 비슷 합 니 다.배경 그림 만 다 를 뿐 입 니 다.즉,이 코드 입 니 다. buffImgG.DrawImageUnscaledAndClipped(SplitedImage[1], ClientRectangle); 적중 하 다 SplitedImage 색인 이 각각 다 르 기 때문에 일일이 반복 하지 않 는 다.
    코드 집합
    그렇다면 완전한 프로그램 은 어떻게 실행 되 어야 합 니까?
    VS 2010 에 새 솔 루 션 을 만 들 었 습 니 다.두 개의 항목 을 추가 하고 하 나 는 WinForm 창 프로그램 입 니 다.이것 은 컨트롤 을 테스트 하 는 데 사 용 됩 니 다.다른 하 나 는 Windows 창 컨트롤 라 이브 러 리 입 니 다.창 컨트롤 라 이브 러 리 의 기본 계승 은 UserControl 이런 종류 이지 만 본 논문 에서 필 자 는 이 를 계승 으로 바 꾸 었 다. PictureBox 클래스,즉 자신 이 만 든 이 컨트롤 은 PictureBox 라 는 유형 에 속 합 니 다. UserControl 
    그래서 완전한 코드 는 다음 과 같다. 
    
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Drawing;
    using System.Drawing.Drawing2D;
    
    using System.Data;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.Diagnostics;
    using System.IO;
    using System.Security.Cryptography;
    using System.Drawing.Imaging;
    
    
    namespace PicBtn
    {
    public partial class RoundPictureBox : PictureBox
    {
    [Category("    "), Description("        ,               ")]
    public bool IsWeightWidthEqual { get; set; }
    //        
    [Category("    "), Description("                    ")]
    public bool IsMultiImage { get; set; }
    //        
    List SplitedImage = null;
    
    Image buffImg;
    Graphics buffImgG;
    public RoundPictureBox()
    {
    InitializeComponent();
    //      
    DoubleBuffered = true;
    SizeMode = PictureBoxSizeMode.Normal;
    //       ,       (    )
    this.ImageLocation = @"D:\  \VS  \PicButton\view_next.png";
    //      
    this.Image = Image.FromFile(ImageLocation);
    //     (Width)164,    4       
    SplitedImage = ImageSplit(164, 4);
    }
    
    
    protected override void OnPaint(PaintEventArgs pe)
    {
    base.OnPaint(pe);
    //      
    buffImg = new Bitmap(Width,Height);
    //          Graphics  
    buffImgG = Graphics.FromImage(buffImg);
    //      ,         
    buffImgG.Clear(this.BackColor);
    
    //     
    pe.Graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
    //   
    pe.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
    
    //    
    GraphicsPath gp = new GraphicsPath();
    //           
    //      
    Rectangle limitedRec = new Rectangle();
    Point startDrawingPoint = new Point(0, 0);
    limitedRec.Location = startDrawingPoint;
    limitedRec.Size = new Size(Width - 1, Height - 1);
    
    if (IsWeightWidthEqual)
    {
    int fixedWidth = Width - 1;
    Height = Width;
    Width = Height;
    limitedRec.Size = new Size(fixedWidth, fixedWidth);
    }
    //                    
    //       
    gp.AddEllipse(limitedRec);
    //      
    Region rg = new Region(gp);
    this.Region = rg;
    //    
    rg.Dispose();
    gp.Dispose();
    }
    
    //              
    /*
    *          (          )
    * 1.       PictureBox(    “   ”),     MouseEnter
    * 2.           ,     MouseDown
    * 3.        ,     MouseUp
    * 4.          ,     MouseLeave
    */
    //1.    
    protected override void OnMouseEnter(EventArgs e)
    {
    base.OnMouseEnter(e);
    using (Graphics g = Graphics.FromHwnd(this.Handle))
    {
    //      
    g.InterpolationMode = InterpolationMode.HighQualityBicubic;
    //    
    g.SmoothingMode = SmoothingMode.AntiAlias;
    //             
    buffImgG.Clear(this.BackColor);
    //              2    
    buffImgG.DrawImageUnscaledAndClipped(SplitedImage[1], ClientRectangle);
    //         buffImgG    Graphics,           
    BufferedGraphics buff = BufferedGraphicsManager.Current.Allocate(buffImgG, ClientRectangle);
    // BufferedGraphics      ,             
    //       DrawImageUnscaledAndClipped
    buff.Graphics.DrawImageUnscaledAndClipped(buffImg, ClientRectangle);
    //             Graphics  
    buff.Render(g);
    }
    }
    //2.    
    protected override void OnMouseDown(MouseEventArgs e)
    {
    base.OnMouseDown(e);
    using (Graphics g = Graphics.FromHwnd(this.Handle))
    {
    g.InterpolationMode = InterpolationMode.HighQualityBicubic;
    g.SmoothingMode = SmoothingMode.HighQuality;
    
    buffImgG.InterpolationMode = InterpolationMode.HighQualityBicubic;
    buffImgG.SmoothingMode = SmoothingMode.HighQuality;
    buffImgG.Clear(BackColor);
    buffImgG.DrawImageUnscaledAndClipped(SplitedImage[2],ClientRectangle);
    BufferedGraphics buff = BufferedGraphicsManager.Current.Allocate(buffImgG, ClientRectangle);
    buff.Graphics.DrawImageUnscaledAndClipped(buffImg, ClientRectangle);
    buff.Render(g);
    }
    }
    
    //3.       
    protected override void OnMouseUp(MouseEventArgs e)
    {
    base.OnMouseUp(e);
    using (Graphics g = Graphics.FromHwnd(this.Handle))
    {
    g.InterpolationMode = InterpolationMode.HighQualityBicubic;
    g.SmoothingMode = SmoothingMode.HighQuality;
    buffImgG.Clear(BackColor);
    buffImgG.DrawImageUnscaledAndClipped(SplitedImage[1], ClientRectangle);
    BufferedGraphics buff = BufferedGraphicsManager.Current.Allocate(buffImgG, ClientRectangle);
    buff.Graphics.DrawImageUnscaledAndClipped(buffImg, ClientRectangle);
    buff.Render(g);
    }
    }
    
    //4.    
    protected override void OnMouseLeave(EventArgs e)
    {
    base.OnMouseLeave(e);
    using (Graphics g = Graphics.FromHwnd(this.Handle))
    {
    g.InterpolationMode = InterpolationMode.HighQualityBicubic;
    g.SmoothingMode = SmoothingMode.HighQuality;
    
    buffImgG.Clear(BackColor);
    buffImgG.DrawImageUnscaledAndClipped(SplitedImage[3], ClientRectangle);
    BufferedGraphics buff = BufferedGraphicsManager.Current.Allocate(buffImgG, ClientRectangle);
    buff.Graphics.DrawImageUnscaledAndClipped(buffImg, ClientRectangle);
    buff.Render(g);
    }
    }
    
    ///
    
    ///       ,            
    ///
    ///       
    ///       ,   1 
    ///         
    private List ImageSplit(int ImageWidth, int SegmentsNum = 1)
    {
    //             
    List SplitedImage = new List();
    //         
    Bitmap SrcBmp = new Bitmap(this.Image);
    //          ARGB 
    PixelFormat ReslouteFormat = PixelFormat.Format32bppArgb;
    //       
    Rectangle SplitAreaRec = new Rectangle();
    //          
    if (ImageWidth <= 0 || SegmentsNum <= 0)
    return SplitedImage;
    else
    {
    //             
    //   0( )   SegmentsNum - 1( )
    for (int i = 0; i < SegmentsNum; i++)
    {
    /*
    *           4    ,         41 * 41
    *                 (     )
    * (0, 0)
    * (41, 0)
    * (82, 0)
    * (123, 0)
    * Y      0
    *
    *           :ImageWidth / SegmentsNum (   /      )
    *    X = i * (ImageWidth / SegmentsNum)
    */
    SplitAreaRec.X = 0 + i * (ImageWidth / SegmentsNum);
    SplitAreaRec.Y = 0;
    //        ,          
    SplitAreaRec.Width = ImageWidth / SegmentsNum;
    SplitAreaRec.Height = ImageWidth / SegmentsNum;
    //         ,       
    Bitmap SplitedBmp = SrcBmp.Clone(SplitAreaRec, ReslouteFormat);
    //      
    SplitedImage.Add(SplitedBmp);
    }
    GC.Collect();
    return SplitedImage;
    }
    }
    }
    }
    
    그리고 디자이너 의 코드:
    
    using System.Windows.Forms;
    namespace PicBtn
    {
    partial class RoundPictureBox
    {
    ///
    
    ///         。
    ///
    private System.ComponentModel.IContainer components = null;
    
    ///
    
    ///            。
    ///
    ///          ,  true;    false。
    protected override void Dispose(bool disposing)
    {
    if (disposing && (components != null))
    {
    components.Dispose();
    }
    base.Dispose(disposing);
    }
    
    #region           
    
    ///
    
    ///            -   
    ///                。
    ///
    private void InitializeComponent()
    {
    components = new System.ComponentModel.Container();
    // this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
    SetStyle(ControlStyles.UserPaint, true);
    SetStyle(ControlStyles.AllPaintingInWmPaint, true); //       .
    SetStyle(ControlStyles.DoubleBuffer, true); //    
    SetStyle(ControlStyles.OptimizedDoubleBuffer, true);//    
    UpdateStyles();
    }
    
    #endregion
    }
    }
    
    솔 루 션 을 만 든 후 창 프로그램 항목 에서 컨트롤 라 이브 러 리 항목 을 참조 해 야 합 니 다.창 디자이너 도구 상자 에서 자신 이 쓴 그림 단추 컨트롤 을 볼 수 있 습 니 다.다음 그림 입 니 다.

    마지막 으로 이 컨트롤 을 자신의 창 에 끌 어 다 놓 으 면 됩 니 다.다시 디 버 깅 하고 실행 하 며 결 과 를 관찰 합 니 다.효과 동적 그림 은 머리말 부분 에 있 습 니 다.
    작성 자:TaeYoona
    출처:https://www.cnblogs.com/SNSD-99/
    이상 은 C\#PictureBox 를 사용 하여 그림 단추 컨트롤 을 실현 하 는 예제 절차 의 상세 한 내용 입 니 다.C\#PictureBox 를 사용 하여 그림 단추 컨트롤 을 실현 하 는 데 관 한 자 료 는 다른 관련 글 을 주목 하 십시오!

    좋은 웹페이지 즐겨찾기