.NET 小物置き場

角丸コンテナ

更新日時 : 2008/10/09 16:10
.NET Framework 2.0 以降で動作します。

コントロールの角を丸くするコンテナです。
デザインモードで使用します。

他のコントロールを内側に貼り付けて、Dock プロパティを Fill にして使用します。
BorderStyle を None にすると、中のコントロールと一体になったような見た目になります。

このコードは、ソリューションエクスプローラから、
プロジェクトに新しい「ユーザーコントロール」を追加して、
ユーザーコントロールのソースの中に貼り付けて使ってください。
そうすることで、 Form のデザイン時のツールボックスに RoundCorner コントロールが出現します。

namespace をプロジェクトで使われている名前に変更してから使用してください。



・使用例
RoundCorner の中に、ツリービューコントロールを貼り付けています。




ソースコード
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Data;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;

namespace Hikipuro.Forms
{
	/// <summary>
	/// 角を丸くするコントロール
	/// <para>
	/// 他のコントロールを内側に貼り付けて、
	/// Dock プロパティを Fill にして使用します。
	/// </para>
	/// </summary>
	[Description("角を丸くするコントロール")]
    [Designer("System.Windows.Forms.Design.ParentControlDesigner, System.Design", typeof(IDesigner))]
    public partial class RoundCorner : UserControl
	{
		/// <summary>
		/// コーナーの角丸のサイズ(直径)
		/// </summary>
		private int cornerR = 10;

		/// <summary>
		/// コーナーの線の太さ
		/// </summary>
		private int penWidth = 3;

		/// <summary>
		/// コーナーの線の色
		/// </summary>
		private Color cornerColor = Color.Red;

		/// <summary>
		/// 内側の領域の色
		/// </summary>
		private Color innerColor = SystemColors.Window;


		//---------------------------------------------------------------------
		#region "デザイン時外部公開プロパティ"
		[Category("Appearance")]
        [Browsable(true)]
		[Description("角の丸さを指定します。(半径)")]
		public int CornerR
		{
			get
			{
				return (int)(cornerR / 2);
			}
			set
			{
				if (value > 0)
					cornerR = value * 2;
				else
					throw new ArgumentException("Corner R", "1 以上の値を入れてください。");

				RenewPadding();
				Refresh();
			}
		}

		[Category("Appearance")]
		[Browsable(true)]
		[Description("内側に塗る色を指定します。")]
		public Color InnerColor
		{
			get
			{
				return innerColor;
			}
			set
			{
				innerColor = value;
				Refresh();
			}
		}

		[Category("Appearance")]
		[Browsable(true)]
		[Description("外枠の色を指定します。")]
		public Color ConerColor
		{
			get
			{
				return cornerColor;
			}
			set
			{
				cornerColor = value;
				Refresh();
			}
		}

		[Category("Appearance")]
		[Browsable(true)]
		[Description("外枠の線の太さを指定します。")]
		public int PenWidth
		{
			get
			{
				return penWidth;
			}
			set
			{
				if (value >= 0)
					penWidth = value;
				else
					throw new ArgumentException("PenWidth", "0 以上の値を入れてください。");

				RenewPadding();
				Refresh();
			}
		}
		#endregion
		//---------------------------------------------------------------------


		/// <summary>
		/// コンストラクタ
		/// </summary>
		public RoundCorner()
		{
			InitializeComponent();

			// コントロールのサイズが変更された時に Paint イベントを発生させる
			SetStyle(ControlStyles.ResizeRedraw, true);
			SetStyle(ControlStyles.SupportsTransparentBackColor, true);

			this.BackColor = Color.Transparent;
			RenewPadding();
		}

		/// <summary>
		/// Paint イベントのオーバーロード
		/// </summary>
		/// <param name="e"></param>
		protected override void OnPaint(PaintEventArgs e)
		{
			//base.OnPaint(e);
			Graphics g = e.Graphics;

			// 描画品質設定
			g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
			//g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
			g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;

			// 変数初期化
			int harfPenWidth = GetHarfPenWidth();

			// ペンとブラシ初期化
			Pen cornerPen = new Pen(cornerColor, penWidth);
			Brush fillBrush = new SolidBrush(innerColor);

			// パスの初期化
			GraphicsPath graphPath = new GraphicsPath();
			graphPath.AddArc(harfPenWidth, harfPenWidth, cornerR, cornerR, 180, 90);
			graphPath.AddArc(this.Width - cornerR - harfPenWidth, harfPenWidth, cornerR, cornerR, 270, 90);
			graphPath.AddArc(this.Width - cornerR - harfPenWidth, this.Height - cornerR - harfPenWidth, cornerR, cornerR, 0, 90);
			graphPath.AddArc(harfPenWidth, this.Height - cornerR - harfPenWidth, cornerR, cornerR, 90, 90);
			graphPath.CloseFigure();

			// パス塗り
			g.FillPath(fillBrush, graphPath);

			// ペンの太さが 1 以上なら外枠描画
			if (penWidth > 0)
				g.DrawPath(cornerPen, graphPath);

			// 後処理
			fillBrush.Dispose();
			cornerPen.Dispose();
		}

		//---------------------------------------------------------------------
		#region "プライベートメソッド"

		/// <summary>
		/// Padding サイズ更新
		/// </summary>
		private void RenewPadding()
		{
			int harfCornerR = (int)(cornerR / 2);
			int adjust = (int)(Math.Cos(45 * Math.PI / 180) * harfCornerR);
			this.Padding = new Padding(harfCornerR + penWidth + 2 - adjust);
		}

		/// <summary>
		/// コーナーの線の太さの半分の太さを取得
		/// </summary>
		/// <returns></returns>
		private int GetHarfPenWidth()
		{
			return (int)Math.Floor((double)(penWidth) / 2 + 0.5);
		}
		#endregion
		//---------------------------------------------------------------------

	}
}