我们必须为RichTextBox
提供选择支持,因此我创建了单独的控件并使用Paint()
方法绘制它。问题是我在完成绘图之后无法编辑RichTextBox
。请找到下面附带的简单样本并分享您的想法。
注意:由于将选择控制停靠栏样式设置为“填充”,我们怀疑是否存在问题,但如果我删除或更改,则选择未绘制。
partial class Form1
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
private GraphicCellControl graphiccell;
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
#region picturebox
this.BackColor = Color.Aquamarine;
var selectBtn = new Button();
selectBtn.Size = new Size(100, 30);
selectBtn.Location = new Point(10, 10);
selectBtn.Text = "Click";
selectBtn.Click += selectBtn_Click;
//var picturebox = new PictureBox();
//picturebox.Size = new Size(140, 110);
//picturebox.Location = new Point(4, 4);
//picturebox.SizeMode = PictureBoxSizeMode.StretchImage;
//picturebox.Image = new Bitmap(@"..\..\Data\picture.png");
var richtextbox = new RichTextBox();
richtextbox.Size = new Size(140, 110);
richtextbox.Location = new Point(4, 4);
richtextbox.Text = "Texting information";
graphiccell = new GraphicCellControl();
graphiccell.Location = new Point(50, 200);
graphiccell.Size = new Size(150, 120);
graphiccell.Controls.Add(richtextbox);
this.Controls.Add(graphiccell);
this.Controls.Add(selectBtn);
#endregion
}
void selectBtn_Click(object sender, EventArgs e)
{
graphiccell.IsSelected = !graphiccell.IsSelected;
}
#endregion
}
public class GraphicCellControl : Control
{
private SelectionControl selectionControl;
public GraphicCellControl()
{
selectionControl = new SelectionControl();
}
private bool isselected;
public bool IsSelected
{
get { return isselected; }
set
{
isselected = value;
if (isselected && !this.Controls.Contains(selectionControl))
{
this.Controls.Add(selectionControl);
selectionControl.BringToFront();
}
else if (!isselected && this.Controls.Contains(selectionControl))
this.Controls.Remove(selectionControl);
}
}
}
public class SelectionControl : Control
{
public SelectionControl()
{
SetStyle(ControlStyles.AllPaintingInWmPaint |
ControlStyles.UserPaint | ControlStyles.Opaque |
ControlStyles.SupportsTransparentBackColor, true);
Dock = DockStyle.Fill;
// Anchor = AnchorStyles.Left | AnchorStyles.Top;
BackColor = Color.Transparent;
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
e.Graphics.DrawRectangle(new Pen(Color.Gray, 1), 4, 4, this.Size.Width - 10, this.Size.Height - 10);
e.Graphics.FillEllipse(Brushes.White, 0, 0, 8, 8);
e.Graphics.FillEllipse(Brushes.White, 0, (this.Size.Height - 10) / 2, 8, 8);
e.Graphics.FillEllipse(Brushes.White, 0, this.Size.Height - 10, 8, 8);
e.Graphics.FillEllipse(Brushes.White, (this.Size.Width - 10) / 2, 0, 8, 8);
e.Graphics.FillEllipse(Brushes.White, (this.Size.Width - 10) / 2, this.Size.Height - 10, 8, 8);
e.Graphics.FillEllipse(Brushes.White, this.Size.Width - 10, 0, 8, 8);
e.Graphics.FillEllipse(Brushes.White, this.Size.Width - 10, (this.Size.Height - 10) / 2, 8, 8);
e.Graphics.FillEllipse(Brushes.White, this.Size.Width - 10, this.Size.Height - 10, 8, 8);
e.Graphics.DrawEllipse(new Pen(Color.DarkGray, 2), 0, 0, 8, 8);
e.Graphics.DrawEllipse(new Pen(Color.DarkGray, 2), 0, (this.Size.Height - 10) / 2, 8, 8);
e.Graphics.DrawEllipse(new Pen(Color.DarkGray, 2), 0, this.Size.Height - 10, 8, 8);
e.Graphics.DrawEllipse(new Pen(Color.DarkGray, 2), (this.Size.Width - 10) / 2, 0, 8, 8);
e.Graphics.DrawEllipse(new Pen(Color.DarkGray, 2), (this.Size.Width - 10) / 2, this.Size.Height - 10, 8, 8);
e.Graphics.DrawEllipse(new Pen(Color.DarkGray, 2), this.Size.Width - 10, 0, 8, 8);
e.Graphics.DrawEllipse(new Pen(Color.DarkGray, 2), this.Size.Width - 10, (this.Size.Height - 10) / 2, 8, 8);
e.Graphics.DrawEllipse(new Pen(Color.DarkGray, 2), this.Size.Width - 10, this.Size.Height - 10, 8, 8);
}
}
答案 0 :(得分:0)
问题的核心,据我所知,您的叠加控制将拦截所有用户的交互。
这不仅适用于鼠标操作。它还包括键盘操作,设置焦点以及在任何更改后更新显示。
可以通过重定向所有相关的WndProc
消息来解决所有这些问题,但它会相当复杂。
这是一个更简单的解决方案:RTB与选择框的重叠,而不是RTB的 。我已经创建了一个修改过的类并且它工作得相当好,虽然可能会调整句柄的大小,使它们动态并使各自的偏移正确,但你可以做到这一点......:
班级与你的基本相同;我刚刚添加了一些属性和Select
方法:
Point oldLocation = Point.Empty;
Control oldParent = null;
BorderStyle oldBorder = BorderStyle.None;
public void Select(Control ctl, bool selected)
{
if (selected)
{
Parent = ctl.Parent;
oldLocation = ctl.Location;
ctl.Location = new Point(8, 8);
Location = Point.Subtract(oldLocation, new Size(8, 8));
Size = new Size(ctl.Width + 16, ctl.Height + 16);
oldParent = ctl.Parent;
oldBorder = (ctl as RichTextBox).BorderStyle; // optional
(ctl as RichTextBox).BorderStyle = BorderStyle.None; // optional
ctl.Parent = this;
this.Show();
}
else
{
ctl.Location = oldLocation;
ctl.Parent = oldParent;
(ctl as RichTextBox).BorderStyle = oldBorder; // optional
this.Hide();
}
}
我最初没有包含BorderStyle
逻辑;我认为这是一些切断像素的原因。不难做对.. ..
另请注意,为了使颜色完全正确,您还需要一个FillRectangle
以避免让父BackColor
流入选择框,具体取决于您拥有的颜色..:
if (Controls.Count > 0)
using (SolidBrush brush = new SolidBrush(Controls[0].BackColor))
e.Graphics.FillRectangle(brush, 4, 4, Width - 10, Height - 10);
答案 1 :(得分:0)
通过研究最终我得到了一个解决方案,将此方法放在selectioncontrol中:
protected override CreateParams CreateParams
{
get
{
var cp = base.CreateParams;
cp.ExStyle |= 0x20;
return cp;
}
}