|
ご回答いただき、ありがとうございます。
早速検証してみました。
こちらの認識違い等ありましたら、ご指摘願います。
#サイズ可変の部分については未調査で、まずは枠線から調査しています。
テキストボックスの枠線について、TextBoxを継承したクラスを実装する方向でとりあえず進めてみました。
OnPaint() の中で、Graphics.DrawRectangle() あるいは ControlPaint.DrawBorder() で枠線を書くことは
できました。
ただ、Azuleanさんご紹介の URL のページにもある通り、この枠線はテキストボックスの「内枠」となり、
通常の枠線とは見た目が異なってしまいます。
それに、SetStyle(ControlStyles.UserPaint, true) が必要であるため、テキストボックスの描画内容を
自前で実装するのは難しいかなと直観しました。
Jitta on the wayさんの仰るように、テキストボックスを使わない方が良かったのかもしれませんが、
現状で機能するところまで作成できており、破線ができなければ実線で妥協しようと思っています。
情報を探してみたところ、Panelの境界線を破線にする方法が以下のページで紹介されています。
http://youryella.wankuma.com/Library/Extensions/Control/BorderDraw.aspx
「それなら破線のPanelの中にテキストボックスを含めたコントロールを作ればいいのでは?」と考えて、
以下のようなクラスを作成してみたところ「外枠」が表示され、私の思っていたような見た目が一応は
実現できました。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Text;
using System.Windows.Forms;
namespace WindowsApplication1
{
public enum BorderStyle : int
{
None = 0,
Dash = 2,
DashDot = 4,
DashDotDot = 5,
Dot = 3,
Solid = 1,
}
public class EmTextBox : Panel
{
private TextBox textBox = null;
public EmTextBox()
{
base.BorderStyle = System.Windows.Forms.BorderStyle.None;
this._BorderColor = Color.Black;
this._BorderStyle = WindowsApplication1.BorderStyle.None;
this._BorderWidth = 1;
this.BackColor = Color.Transparent;
textBox = new TextBox();
textBox.BorderStyle = System.Windows.Forms.BorderStyle.None;
textBox.Location = new Point(0, 0);
textBox.Multiline = true;
this.Controls.Add(textBox);
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
if (this.BorderStyle != BorderStyle.None)
{
using (Pen p = new Pen(this.BorderColor, this.BorderWidth))
{
p.DashStyle = this.ConvertToDashStyle(this.BorderStyle);
Rectangle r = this.ClientRectangle;
r.X += r.X + Convert.ToInt32(decimal.Floor(Convert.ToDecimal(this.BorderWidth / 2)));
r.Y += r.Y + Convert.ToInt32(decimal.Floor(Convert.ToDecimal(this.BorderWidth / 2)));
r.Width -= this.BorderWidth;
r.Height -= this.BorderWidth;
e.Graphics.DrawRectangle(p, r);
}
}
}
protected override void OnResize(EventArgs eventargs)
{
base.OnResize(eventargs);
if (this.BorderStyle == BorderStyle.None)
{
textBox.Size = this.Size;
}
else
{
int padding = this.BorderWidth * 2;
textBox.Size = new Size(this.Width - padding, this.Height - padding);
}
}
protected override void OnLocationChanged(EventArgs e)
{
base.OnLocationChanged(e);
if (this.BorderStyle == BorderStyle.None)
{
textBox.Location = new Point(0, 0);
}
else
{
textBox.Location = new Point(this.BorderWidth, this.BorderWidth);
}
}
private DashStyle ConvertToDashStyle(WindowsApplication1.BorderStyle style)
{
return (DashStyle)style - 1;
}
private Color _BorderColor;
[Category("表示")]
[DefaultValue(typeof(Color), "Black")]
[Description("コントロールの境界線色を取得または設定します。")]
public Color BorderColor
{
get { return this._BorderColor; }
set
{
this._BorderColor = value;
this.Invalidate();
}
}
private BorderStyle _BorderStyle;
[Category("表示")]
[DefaultValue(typeof(BorderStyle), "None")]
[Description("コントロールの境界線スタイルを取得または設定します。")]
public new BorderStyle BorderStyle
{
get { return this._BorderStyle; }
set
{
this._BorderStyle = value;
this.Invalidate();
}
}
private int _BorderWidth;
[Category("表示")]
[DefaultValue(1)]
[Description("コントロールの境界線の幅を取得または設定します。")]
public int BorderWidth
{
get { return this._BorderWidth; }
set
{
this._BorderWidth = value;
this.Invalidate();
if (this.BorderStyle == BorderStyle.None)
{
textBox.Size = this.Size;
}
else
{
int padding = this.BorderWidth * 2;
textBox.Size = new Size(this.Width - padding, this.Height - padding);
}
}
}
}
}
ただし、Panelを継承したテキストボックスというのが、私はとても気に入りません。
こういうやり方はよくないのでしょうか?
|