C\#PictureBox 를 사용 하여 그림 단추 컨트롤 을 실현 하 는 예제 절차
우 리 는 때때로 프로그램의 폴 더 에서 아이콘 을 볼 수 있 는데,이 아이콘 들 은 마침 단추 의 배경 그림 으로 사용 된다.마우스 포인터 가 서로 다른 상태 에 있 을 때'들 어가 기 버튼','왼쪽 버튼 누 르 기','놓 기','떠 나 기 버튼'이 있 으 면 단추 의 배경 그림 도 바 뀌 고 있다.이 사진 들 은 대체로 다음 과 같다.
전문 은 첫 번 째 그림 소 재 를 예 로 들 면 이 그림 은 4 단(아래 그림 참조)으로 나 눌 수 있 는데 마침 마우스 포인터 가 컨트롤 을 조작 할 때 각각 다른 상 태 를 나타 내 고 왼쪽 에서 오른쪽으로'초기 상태'(기본 표시 배경),'포인터 가 버튼 영역 에 들 어가 거나 마우스 왼쪽 단 추 를 누 르 면 풀 리 지 않 음','마우스 왼쪽 단 추 를 누 르 면 움 직 이지 않 음'으로 나 타 났 다."마우스 포인터 가 단추 영역 을 떠 납 니 다"
자체 적 으로 이 사진 소 재 는 매우 교묘 하 게 디자인 되 었 는데 그 사 이 즈 는 164*41 이기 때문에 한 단락 의 사 이 즈 는 딱 41*41 이다.
코드 를 붙 이기 전에 먼저 효 과 를 보십시오.
컴 파일 환경 및 설명
이미지 소재 분할
분명히 상기 사진 소 재 는 4 단 으로 나 누 어 마우스 포인터 로 서 의 서로 다른 상태 로 나 누 어 분할 을 실현 하 는 방향 은?
그림 을 Image 대상 으로 변환 합 니 다
여기 서 함 수 를 정의 할 수 있다. 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(컨트롤 그리 기 이벤트)
우선 사용자 정의 컨트롤 클래스 에서 개인 대상,버퍼 를 정의 합 니 다. 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 를 사용 하여 그림 단추 컨트롤 을 실현 하 는 데 관 한 자 료 는 다른 관련 글 을 주목 하 십시오!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
C#Task를 사용하여 비동기식 작업을 수행하는 방법라인이 완성된 후에 이 라인을 다시 시작할 수 없습니다.반대로 조인(Join)만 결합할 수 있습니다 (프로세스가 현재 라인을 막습니다). 임무는 조합할 수 있는 것이다. 연장을 사용하여 그것들을 한데 연결시키는 것이...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.