tamaño resolucion redimensionar pantalla obtener maximizar formularios formulario escala controles completa autoscalemode automático ajuste ajustar c# .net winforms user-controls windows-forms-designer

c# - resolucion - Control de usuario con propiedad de altura automática



obtener resolucion de pantalla c# (1)

Quiero crear un control de usuario que muestre el texto.
Necesito una forma de cambiar el tamaño del control en tiempo de ejecución para que ajuste la altura para mostrar todo el texto. Creé un control que se ve así:

Como puede ver, tengo el icono y el texto dibujados con TextRenderer.DrawText . Lamentablemente, cuando cambio el tamaño de mi control (solo a la izquierda o a la derecha) mi texto a veces se corta, asno se muestra a continuación:

Estoy midiendo texto usando TextRenderer.MeasureText basado en que estoy contando el número de líneas y luego estoy dibujando ese texto. Aquí está el código que estoy usando:

[Designer(typeof(MyTextBoxDesigner))] public partial class MyTextBox : UserControl { public MyTextBox() { InitializeComponent(); } [DefaultValue("Demo"), Description("Text of control"), Category("Appearance"),Browsable(true)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] public override string Text { get { return base.Text; } set { if (base.Text == value) return; base.Text = value; Invalidate(); } } Image _image; [Description("Image shown on the left side of the control"), Category("Appearance")] public Image Image { get { return _image; } set { if (_image == value) return; _image = value; Invalidate(); } } protected override void OnPaint(PaintEventArgs e) { int imagePadding = 0; if (_image != null) { imagePadding = 25; e.Graphics.DrawImage(_image,new Rectangle(5,5,16,16)); } Size textSize1 = TextRenderer.MeasureText(e.Graphics, Text, Font); SizeF textSize2 = e.Graphics.MeasureString(Text, Font); Debug.WriteLine(textSize2); int maxTextWidth = Width - Padding.Left-Padding.Right-imagePadding; int lineHeight = textSize1.Height + 2; int numLines = 1; if (textSize1.Width > maxTextWidth) { numLines = textSize1.Width / maxTextWidth + 1; } Rectangle textRect = new Rectangle { Width = Width - Padding.Left-Padding.Right-imagePadding, Height = (numLines * lineHeight), X = Padding.Left+imagePadding, Y = 5 }; TextRenderer.DrawText(e.Graphics, Text, Font, textRect, ForeColor, TextFormatFlags.WordBreak | TextFormatFlags.Left | TextFormatFlags.Top); e.Graphics.DrawRectangle(Pens.CadetBlue, textRect); base.OnPaint(e); } } internal class MyTextBoxDesigner : ControlDesigner { public override SelectionRules SelectionRules { get { //all minus bottom and top return (base.SelectionRules & ~(SelectionRules.BottomSizeable | SelectionRules.TopSizeable)); } } }

Idealmente, me gustaría que mi control autoajuste la altura según la longitud del texto, por lo que si el texto es corto (o el tiempo suficiente), por ejemplo, 20px de altura, pero si el texto es largo, mi control debería ser (por ejemplo) 40px altura (2 líneas de texto).

¿Cómo debo cambiar mi medición de texto para calcular el textRect correctamente?
¿Debo actualizar la altura de mi control usando la propiedad Tamaño o hay una forma mejor?

EDITAR: Básicamente quiero dibujar texto que pueda envolver dentro de un rectángulo, pero que tenga un ancho fijo, de modo que cuando el texto sea más largo, ese rectángulo ajustará su altura. Luego, en función de esa altura, quiero ajustar la altura de control.


Aquí hay un control automático de altura. Si cambia el ancho del control, la altura del control cambiará de manera que se pueda mostrar todo el texto.

Puede crear dicho control utilizando diferentes enfoques que incluyen:

  • Método 1: Control compuesto de tamaño automático que aloja una etiqueta
    Este enfoque se basa en alojar una Label tamaño automático con ancho máximo dinámico en un Control tamaño automático. En este enfoque, establecemos el ancho máximo de etiqueta según el ancho de control y, dado que la etiqueta es de tamaño automático, su altura se configurará automáticamente para mostrar todos los textos y luego estableceremos la altura del control en función de la altura de la etiqueta.

  • Enfoque 2: control simple de tamaño automático desde cero sin etiqueta
    Este enfoque se basa en anular SetBoundsCore y establecer el tamaño de control en función de su tamaño de Text . En este enfoque calculamos el tamaño del texto en función del ancho de control utilizando TextRenderer.MeasureText y luego establecemos la altura calculada como la altura del control. En este enfoque, debe manejar los indicadores de formato de texto y representarse usted mismo.

En ambos enfoques, un ControlDesigner se usa para deshabilitar todos los ControlDesigner tamaño, excepto izquierdo y derecho.

tenga en cuenta

Estos no son los únicos enfoques disponibles, pero son buenos ejemplos. Como otra opción, puede heredar de una Label y cambiar su comportamiento.

Método 1: Control compuesto de tamaño automático que aloja una etiqueta

Funciona sobre la base de establecer la propiedad AutoSize de label en true y luego establecer MaximumSize de label en función del Width contol. También la altura del control se establece en función de la altura de la etiqueta. Simplemente puede dibujar la imagen en el método OnPaint . También puede agregar un PictureBox para la imagen.

using System; using System.ComponentModel; using System.Drawing; using System.Windows.Forms; [Designer(typeof(MyLabelDesigner))] public partial class MyLabel : Control { public MyLabel() { InitializeComponent(); } private System.Windows.Forms.Label textLabel; private void InitializeComponent() { this.textLabel = new System.Windows.Forms.Label(); this.textLabel.AutoSize = true; this.textLabel.Location = new System.Drawing.Point(0, 0); this.textLabel.Name = "label1"; textLabel.SizeChanged += new EventHandler(textLabel_SizeChanged); this.AutoSize = true; this.Controls.Add(this.textLabel); } void textLabel_SizeChanged(object sender, EventArgs e) { this.Height = this.textLabel.Bottom + 0; } protected override void OnSizeChanged(EventArgs e) { base.OnSizeChanged(e); this.textLabel.MaximumSize = new Size(this.Width, 0); } [Browsable(true)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] public override string Text { get { return this.textLabel.Text; } set { this.textLabel.Text = value; } } }

Enfoque 2: control simple de tamaño automático desde cero sin etiqueta

Este enfoque funciona según el tamaño de control establecido en SetBoundsCore en función del ancho actual y la altura calculada de su Text . Para calcular la altura del control. Simplemente puede dibujar la Image .

using System.Windows.Forms; using System.Drawing; using System.ComponentModel; using System.Windows.Forms.Design; [Designer(typeof(MyLabelDesigner))] public class ExLabel : Control { public ExLabel() { AutoSize = true; DoubleBuffered = true; SetStyle(ControlStyles.ResizeRedraw, true); } protected override void OnTextChanged(System.EventArgs e) { base.OnTextChanged(e); SetBoundsCore(Left, Top, Width, Height, BoundsSpecified.Size); Invalidate(); } protected override void SetBoundsCore(int x, int y, int width, int height, BoundsSpecified specified) { var flags = TextFormatFlags.Left | TextFormatFlags.WordBreak; var proposedSize = new Size(width, int.MaxValue); var size = TextRenderer.MeasureText(Text, Font, proposedSize, flags); height = size.Height; base.SetBoundsCore(x, y, width, height, specified); } protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); var flags = TextFormatFlags.Left | TextFormatFlags.WordBreak; TextRenderer.DrawText(e.Graphics, Text, Font, ClientRectangle, ForeColor, BackColor, flags); } }

Diseñador

Aquí está el ControlDesigner que solía limitar los manejadores de agarre de tamaño en el diseñador hacia la izquierda y hacia la derecha para ambas implementaciones:

using System.Windows.Forms.Design; public class MyLabelDesigner : ControlDesigner { public override SelectionRules SelectionRules { get { return (base.SelectionRules & ~(SelectionRules.BottomSizeable | SelectionRules.TopSizeable)); } } }