C# 在背景控件中的其他控件上绘制时,如何使背景控件可编辑
我们必须为C# 在背景控件中的其他控件上绘制时,如何使背景控件可编辑,c#,windows,winforms,C#,Windows,Winforms,我们必须为RichTextBox提供选择支持,因此我创建了单独的控件,并使用Paint()方法对其进行绘制。问题是,我无法编辑RichTextBox,一旦在其上完成绘图。请找到下面所附的简单示例并分享您的想法 注意:由于将“选择控件停靠样式”设置为“填充”,我们怀疑存在问题,但如果我删除或更改了该选项,则不会绘制该选项 部分类表单1 { /// ///必需的设计器变量。 /// private System.ComponentModel.IContainer components=null
RichTextBox
提供选择支持,因此我创建了单独的控件,并使用Paint()
方法对其进行绘制。问题是,我无法编辑RichTextBox
,一旦在其上完成绘图。请找到下面所附的简单示例并分享您的想法
注意:由于将“选择控件停靠样式”设置为“填充”,我们怀疑存在问题,但如果我删除或更改了该选项,则不会绘制该选项
部分类表单1
{
///
///必需的设计器变量。
///
private System.ComponentModel.IContainer components=null;
///
///清理所有正在使用的资源。
///
///如果应释放托管资源,则为true;否则为false。
受保护的覆盖无效处置(布尔处置)
{
if(处理和(组件!=null))
{
组件。Dispose();
}
基地。处置(处置);
}
#区域Windows窗体设计器生成的代码
专用graphiccell控制graphiccell;
///
///设计器支持所需的方法-不修改
///此方法的内容与代码编辑器一起使用。
///
私有void InitializeComponent()
{
#区域图片盒
this.BackColor=Color.Aquamarine;
var selectBtn=新建按钮();
选择BTN.Size=新尺寸(100,30);
选择BTN.Location=新点(10,10);
选择btn.Text=“单击”;
选择BTN。单击+=选择BTN\u单击;
//var picturebox=新的picturebox();
//picturebox.Size=新尺寸(140110);
//picturebox.Location=新点(4,4);
//picturebox.SizeMode=PictureBoxSizeMode.StretchImage;
//picturebox.Image=新位图(@.\..\Data\picture.png);
var richtextbox=新的richtextbox();
richtextbox.Size=新的大小(140110);
richtextbox.Location=新点(4,4);
richtextbox.Text=“文本信息”;
graphiccell=新的GraphicCellControl();
graphiccell.Location=新点(50200);
graphiccell.Size=新的大小(150120);
graphiccell.Controls.Add(richtextbox);
this.Controls.Add(graphiccell);
this.Controls.Add(选择BTN);
#端区
}
void selectBtn\u单击(对象发送者,事件参数e)
{
graphiccell.IsSelected=!graphiccell.IsSelected;
}
#端区
}
公共类GraphicCellControl:控件
{
私人选择控制选择控制;
公共图形控制()
{
selectionControl=新建selectionControl();
}
私人布尔当选;
公选学校
{
获取{return isselected;}
设置
{
isselected=值;
if(isselected&!this.Controls.Contains(selectionControl))
{
this.Controls.Add(selectionControl);
selectionControl.BringToFront();
}
如果(!isselected&&this.Controls.Contains(selectionControl))
this.Controls.Remove(selectionControl);
}
}
}
公共类SelectionControl:Control
{
公共选择控制()
{
设置样式(ControlStyles.AllPaintingInWmPaint|
ControlStyles.UserPaint | ControlStyles.不透明|
ControlStyles.SupportsTransparentBackColor,true);
Dock=DockStyle.Fill;
//锚点=锚点样式。左|锚点样式。顶部;
背景色=颜色。透明;
}
受保护的覆盖无效OnPaint(PaintEventArgs e)
{
基础漆(e);
e、 Graphics.SmoothingMode=SmoothingMode.AntiAlias;
e、 Graphics.DrawRectangle(新笔(Color.Gray,1),4,4,this.Size.Width-10,this.Size.Height-10);
e、 图形。填充椭圆(画笔。白色,0,0,8,8);
e、 图形.填充椭圆(画笔.White,0,(this.Size.Height-10)/2,8,8);
e、 Graphics.FillEllipse(画笔.White,0,this.Size.Height-10,8,8);
e、 图形.FillEllipse(画笔.White,(this.Size.Width-10)/2,0,8,8);
e、 Graphics.FillEllipse(笔刷.White,(this.Size.Width-10)/2,this.Size.Height-10,8,8);
e、 图形.FillEllipse(画笔.White,this.Size.Width-10,0,8,8);
e、 Graphics.FillEllipse(画笔.White,this.Size.Width-10,(this.Size.Height-10)/2,8,8);
e、 Graphics.FillEllipse(画笔.White,this.Size.Width-10,this.Size.Height-10,8,8);
e、 图形学.抽屉式(新钢笔(彩色暗灰色,2),0,0,8,8);
e、 Graphics.Dropellipse(新笔(Color.DarkGray,2),0,(this.Size.Height-10)/2,8,8);
e、 Graphics.Dropellipse(新笔(Color.DarkGray,2),0,this.Size.Height-10,8,8);
e、 Graphics.Dropellipse(新钢笔(Color.DarkGray,2),(this.Size.Width-10)/2,0,8,8);
e、 Graphics.Dropellipse(新笔(Color.DarkGray,2),(this.Size.Width-10)/2,this.Size.Height-10,8,8);
e、 Graphics.Dropellipse(新钢笔(Color.DarkGray,2),this.Size.Width-10,0,8,8);
e、 Graphics.Dropellipse(新笔(Color.DarkGray,2),this.Size.Width-10,(this.Size.Height-10)/2,8,8);
e、 Graphics.Dropellipse(新钢笔(Color.DarkGray,2),this.Size.Width-10,this.Size.Height-10,8,8);
}
}
据我所知,问题的核心是覆盖控件将拦截所有用户交互
这不仅仅适用于鼠标操作。它还包括键盘操作、设置焦点和在任何更改后更新显示
通过重定向所有相关的WndProc
消息,可以解决所有这些问题,但这将相当复杂
这里有一个更简单的解决方案:不是用选择框覆盖RTB,而是将该框置于RTB下方。我已经创建了一个修改过的类,它工作得相当好,尽管有人可能会调整
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);
}
}
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();
}
}
if (Controls.Count > 0)
using (SolidBrush brush = new SolidBrush(Controls[0].BackColor))
e.Graphics.FillRectangle(brush, 4, 4, Width - 10, Height - 10);
protected override CreateParams CreateParams
{
get
{
var cp = base.CreateParams;
cp.ExStyle |= 0x20;
return cp;
}
}