如何覆盖WinForms文本框的首选大小?
NET中的如何覆盖WinForms文本框的首选大小?,winforms,autosize,Winforms,Autosize,NET中的文本框不允许您调整其高度(有选项) 我有一个: 示例1: 示例2: 我需要的是修正计算;覆盖.NET WinFormsTextBox控件中的错误 我创建了一个后代FixedTextBox,并尝试覆盖受保护的: 我的重写方法正在被调用,但是文本框没有改变它的“首选”大小 我还尝试覆盖受保护的DefaultSize属性: protected override Size DefaultSize { get { Size size = base.Default
文本框
不允许您调整其高度(有选项)
我有一个:
示例1:
示例2:
我需要的是修正计算;覆盖.NET WinFormsTextBox
控件中的错误
我创建了一个后代FixedTextBox
,并尝试覆盖受保护的:
我的重写方法正在被调用,但是文本框
没有改变它的“首选”大小
我还尝试覆盖受保护的DefaultSize
属性:
protected override Size DefaultSize
{
get
{
Size size = base.DefaultSize;
if (this.BorderStyle == BorderStyle.None)
{
size.Height += 2;
}
return size;
}
}
它在构造期间被调用,但当“默认大小”不同时(例如,在我更改边框样式之后),它将不再被调用,并且不会影响文本框的大小
什么是连接到.NET WinForms“AutoSize”基础结构以调整“首选”大小的正确方法
注意:仅仅因为我覆盖了GetPreferredSize
并不意味着解决方案涉及覆盖GetPreferredSize
tl;dr:有人走进textBox1.Height+=1
,想一想为什么它什么都不做
相关(但不同)问题
-
提出问题,接受解决方案;与此相反,这个问题询问如何在WinForms中使用“首选大小”基础结构
-
提到这个问题,寻找解决方案,包括让文本框重新计算其首选高度;与此相反,这个问题承认文本框无法重新计算其首选高度,即使可以,也不会有帮助,因为自动大小计算是错误的
有关SO问题,请参见菲尔·赖特的答案:
“作为布局周期的一部分,容器调用Control.GetPreferredSize
如果可能的话,它允许被调用控件返回它们想要的大小。但是,容器不必满足此请求的大小。例如,当控件的Dock设置为Top时,无论GetPreferredSize方法返回的值如何,宽度都将定义为包含控件的宽度。这满足了hod对于像flow layout控件这样的容器特别有用,它将一个接一个地定位每个子控件。“[Phil Wright]
这意味着此PreferredSize不会更改文本框的大小
我认为这解决了你的问题:
public class MyTextBox : TextBox
{
const int RequestedHight = 30;
protected override void OnSizeChanged(EventArgs e)
{
base.OnSizeChanged(e);
AssureRequestedHight();
}
protected override void OnCreateControl()
{
base.OnCreateControl();
AssureRequestedHight();
}
private void AssureRequestedHight()
{
if (this.Size.Height != RequestedHight && !this.Multiline) {
this.Multiline = true;
this.MinimumSize = new Size(0, RequestedHight);
this.Size = new Size(this.Size.Width, RequestedHight);
this.Multiline = false;
}
}
}
你有没有试过做一个覆盖
protected override System.Drawing.Size DefaultSize
{ get { return new System.Drawing.Size( 145, 52 ); } }
或者你需要的任何尺寸
根据您的目的,我过去所做的事情是为某些控件创建自己的子类,并重写诸如FontSize、FontName、Size等内容,使它们都成为只读的(仅应用外部可见的“getter”)。通过这样做,任何放在具有设计时序列化的WinForms窗体上的类实例都会让我烦恼,无法从设计器中删除“只读”属性。在开发早期这样做之后,这些控件再也没有出现问题。如果我更改了它,表单将在设计器中获得最新的值/大小/字体,而无需遍历每个表单和控件的每个实例
我发现它可以很好地处理一些事情,比如只显示日期的文本框,或者日期/时间字段,另外还可以应用于标签、命令按钮和其他“通用”的elmeents。因此,在整个应用程序中,它几乎就像应用级联样式表,但在WinForms级别
只是一个想法,希望它能为您打开另一条解决困境的途径。我找到了解决富文本框高度问题的方法。。我把它改成了通用的
在应用程序中创建以下结构….
[StructLayout(LayoutKind.Sequential)]
public struct RECT {
public Int32 left;
public Int32 top;
public Int32 right;
public Int32 bottom;
}
[StructLayout(LayoutKind.Sequential)]
public struct SCROLLBARINFO {
public Int32 cbSize;
public RECT rcScrollBar;
public Int32 dxyLineButton;
public Int32 xyThumbTop;
public Int32 xyThumbBottom;
public Int32 reserved;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
public Int32[] rgstate;
}
在类中为表单创建以下私有变量(需要计算富文本高度的地方)
将以下方法添加到窗体的类中
private int CalculateRichTextHeight(string richText) {
int height = 0;
RichTextBox richTextBox = new RichTextBox();
richTextBox.Rtf = richText;
richTextBox.Height = this.Bounds.Height;
richTextBox.Width = this.Bounds.Width;
richTextBox.WordWrap = false;
int nHeight = 0;
int nMin = 0, nMax = 0;
SCROLLBARINFO psbi = new SCROLLBARINFO();
psbi.cbSize = Marshal.SizeOf(psbi);
richTextBox.Height = 10;
richTextBox.ScrollBars = RichTextBoxScrollBars.Vertical;
int nResult = GetScrollBarInfo(richTextBox.Handle, OBJID_VSCROLL, ref psbi);
if (psbi.rgstate[0] == 0) {
GetScrollRange(richTextBox.Handle, SB_VERT, out nMin, out nMax);
height = (nMax - nMin);
}
return height;
}
您可能需要修改上述方法,使其按照您的要求工作。。。
确保将Rtf字符串作为参数发送给方法not normal text,并确保为方法中的Richtextbox变量指定可用的宽度和高度
您可以根据您的要求使用WordWrap 我做到了;它不会影响文本框的大小。@IanBoyd,请参阅修订答案中的注释,这很好;我注意到,我随机尝试覆盖TextBox
的随机方法可能与正确的方法没有任何关系。没有“官方”的正确方法,因为TextBox的这种行为没有文档记录。这真的只是我通过反复试验发现的一个棘手的解决办法。当文本框在多行模式下工作时,可以在设计器中使用鼠标或在属性网格中更改文本框的高度,当然也可以通过编程方式更改文本框的高度。其想法是将文本框暂时切换到多行模式,并更改高度。这一点本身不起作用,但如果同时相应地设置了最小大小,那么显然它起作用了。
private UInt32 SB_VERT = 1;
private UInt32 OBJID_VSCROLL = 0xFFFFFFFB;
[DllImport("user32.dll")]
private static extern
Int32 GetScrollRange(IntPtr hWnd, UInt32 nBar, out Int32 lpMinPos, out Int32 lpMaxPos);
[DllImport("user32.dll")]
private static extern
Int32 GetScrollBarInfo(IntPtr hWnd, UInt32 idObject, ref SCROLLBARINFO psbi);
private int CalculateRichTextHeight(string richText) {
int height = 0;
RichTextBox richTextBox = new RichTextBox();
richTextBox.Rtf = richText;
richTextBox.Height = this.Bounds.Height;
richTextBox.Width = this.Bounds.Width;
richTextBox.WordWrap = false;
int nHeight = 0;
int nMin = 0, nMax = 0;
SCROLLBARINFO psbi = new SCROLLBARINFO();
psbi.cbSize = Marshal.SizeOf(psbi);
richTextBox.Height = 10;
richTextBox.ScrollBars = RichTextBoxScrollBars.Vertical;
int nResult = GetScrollBarInfo(richTextBox.Handle, OBJID_VSCROLL, ref psbi);
if (psbi.rgstate[0] == 0) {
GetScrollRange(richTextBox.Handle, SB_VERT, out nMin, out nMax);
height = (nMax - nMin);
}
return height;
}