visual studio instalar hacer formulario form como aplicacion aparece agregar c# wpf visual-studio windows-forms-designer vsix

instalar - windows forms c# visual studio 2017 pdf



Dibuje adornos en windows.forms.controls en Visual Studio Designer desde una extensión (3)

Creo que estás buscando BehaviorService arquitectura de BehaviorService . Aquí se explica la arquitectura con partes de apoyo como Behavior , Adorner y Glyph y algunos ejemplos. Descripción general del servicio de comportamiento . Por ejemplo

Ampliación de la interfaz de usuario en tiempo de diseño

El modelo BehaviorService permite que la nueva funcionalidad se pueda colocar fácilmente en capas en una interfaz de usuario de diseñador existente. La nueva interfaz de usuario permanece independiente de otros objetos Glyph y Behavior definidos previamente. Por ejemplo, las etiquetas inteligentes en algunos controles son accedidas por un glifo en la esquina superior derecha del control (Glifo de etiqueta inteligente).

El código de etiqueta inteligente crea su propia capa Adorner y agrega objetos Glyph a esta capa. Esto mantiene los objetos de glifos de etiquetas inteligentes separados de los objetos de glifos de selección. El código necesario para agregar un nuevo Adorner a la colección Adorners es sencillo.

etc.

Espero que ayude.

Escribí una extensión de Visual Studio 2013 que observa las ventanas del diseñador Windows.Forms. Cuando un desarrollador está cambiando los controles en la ventana del diseñador, la extensión intenta verificar que el resultado sea consistente con nuestras pautas de estilo de interfaz de usuario. Si se encuentran posibles infracciones, se enumeran en una ventana de herramientas. Todo esto funciona bien. Pero ahora me gustaría marcar los controles inconsistentes en la ventana del diseñador, por ejemplo, con un marco rojo o algo así.

Desafortunadamente, no encontré una forma de dibujar adornos en los controles en una ventana de diseñador. Sé que puedes dibujar esos adornos si desarrollas tu propio ControlDesigner , pero necesito hacerlo desde "fuera" del diseñador del control. Solo tengo el IDesignerHost de Dte2.ActiveWindow y puedo acceder a los Controls y ControlDesigners a través de ese host. No pude encontrar ninguna forma de agregar adornos desde "fuera" de los ControlDesigners. Mi solución por ahora es capturar los eventos de pintura de los controles e intentar dibujar mis adornos desde allí. Esto no funciona bien para todos los controles (es decir, ComboBoxes, etc.), porque no todos los controles le permiten dibujar sobre ellos. Así que tuve que usar el evento Paint de su control de padres. Y hay otros inconvenientes a esta solución.

Espero que alguien pueda decirme si hay una mejor manera. Estoy bastante seguro de que tiene que haber uno: si usa Menú-> Ver-> Orden de tabulación (no estoy seguro del título correcto del menú en inglés, estoy usando un IDE alemán), puede ver que el IDE en sí es capaz de adornar controles (no captura de pantalla porque es mi primera publicación en SO), y estoy seguro de que no está utilizando un trabajo como yo. ¿Como hace eso?

He estado buscando en Google por semanas ahora. Gracias por cualquier ayuda, consejo, investigación puntos de partida ....

ACTUALIZAR:

Tal vez se aclare un poco más con esta captura de pantalla:

Esos caretes numerados en azul es lo que Visual Studio muestra cuando selecciona Orden de pestañas en el menú Ver. Y mi pregunta es cómo lo hace el IDE.

Como se mencionó, intenté hacerlo en el evento Paint de los controles, pero, por ejemplo, ComboBox no es compatible con ese evento. Y si uso el evento Paint los padres, solo puedo dibujar "alrededor" de los controles hijos porque están pintados después de los padres.

También pensé en usar la reflexión en los controles o en los ControlDesigner s, pero no estoy seguro de cómo conectar el método de OnPaintAdornments protegido. Y no creo que los desarrolladores de IDE hayan usado esos trucos "sucios".


Finalmente tuve el tiempo para implementar mi solución y quiero mostrarla para que esté completa.
Por supuesto, reduje el código para mostrar solo las partes relevantes.

1. Obtención del Servicio de Comportamiento

Esta es una de las razones por las que no me gusta el patrón de localización (anti) del servicio . Aunque leí muchos artículos, no pensé que pudiera obtener un Servicio de BehaviorService de mi IDesignerHost .

Ahora tengo algo como esta clase de datos:

public class DesignerIssuesModel { private readonly BehaviorService m_BehaviorService; private readonly Adorner m_Adorner = new Adorner(); private readonly Dictionary<Control, MyGlyph> m_Glyphs = new Dictionary<Control, MyGlyph>(); public IDesignerHost DesignerHost { get; private set; } public DesignerIssuesModel(IDesignerHost designerHost) { DesignerHost = designerHost; m_BehaviorService = (BehaviorService)DesignerHost.RootComponent.Site.GetService(typeof(BehaviorService)); m_BehaviorService.Adornders.Add(m_Adorner); } public void AddIssue(Control control) { if (!m_Glyphs.ContainsKey(control)) { MyGlyph g = new MyGlyph(m_BehaviorService, control); m_Glyphs[control] = g; m_Adorner.Glyphs.Add(g); } m_Glyphs[control].Issues += 1; } public void RemoveIssue(Control control) { if (!m_Glyphs.ContainsKey(control)) return; MyGlyph g = m_Glyphs[control]; g.Issues -= 1; if (g.Issues > 0) return; m_Glyphs.Remove(control); m_Adorner.Glyphs.Remove(g); } }

Así que RootComponent el BehaviorService del RootComponent del IDesignerHost y agrego un nuevo System.Windows.Forms.Design.Behavior.Adorner a él. Luego puedo usar mis métodos AddIssue y RemoveIssue para agregar y modificar mis glifos al Adorner .

2. Mi implementación de glifos

Aquí está la implementación de MyGlyph , una clase heredada de `System.Windows.Forms.Design.Behavior.Glyph :

public class MyGlyph : Glyph { private readonly BehaviorService m_BehaviorService; private readonly Control m_Control; public int Issues { get; set; } public Control Control { get { return m_Control; } } public VolkerIssueGlyph(BehaviorService behaviorService, Control control) : base(new MyBehavior()) { m_Control = control; m_BehaviorService = behaviorService; } public override Rectangle Bounds { get { Point p = m_BehaviorService.ControlToAdornerWindow(m_Control); Graphics g = Graphics.FromHwnd(m_Control.Handle); SizeF size = g.MeasureString(Issues.ToString(), m_Font); return new Rectangle(p.X + 1, p.Y + m_Control.Height - (int)size.Height - 2, (int)size.Width + 1, (int)size.Height + 1); } } public override Cursor GetHitTest(Point p) { return m_Control.Visible && Bounds.Contains(p) ? Cursors.Cross : null; } public override void Paint(PaintEventArgs pe) { if (!m_Control.Visible) return; Point topLeft = m_BehaviorService.ControlToAdornerWindow(m_Control); using (Pen pen = new Pen(Color.Red, 2)) pe.Graphics.DrawRectangle(pen, topLeft.X, topLeft.Y, m_Control.Width, m_Control.Height); Rectangle bounds = Bounds; pe.Graphics.FillRectangle(Brushes.Red, bounds); pe.Graphics.DrawString(Issues.ToString(), m_Font, Brushes.Black, bounds); } }

Los detalles de las anulaciones se pueden estudiar en los enlaces publicados en la respuesta aceptada.
Trazo un borde rojo alrededor (pero dentro) del control y agrego un pequeño rectángulo que contiene el número de problemas encontrados.
Una cosa a tener en cuenta es que Control.Visible si Control.Visible es true . Por lo tanto, puedo evitar dibujar el adorno cuando el control está, por ejemplo, en una TabPage que actualmente no está seleccionada.

3. Mi implementación de comportamiento

Dado que el constructor de la clase base Glyph necesita una instancia de una clase heredada de Behavior , necesitaba crear una nueva clase. Esto se puede dejar vacío, pero lo usé para mostrar una información sobre herramientas cuando el mouse entra en el rectángulo y muestra el número de problemas:

public class MyBehavior : Behavior { private static readonly ToolTip ToolTip = new ToolTip { ToolTipTitle = "UI guide line issues found", ToolTipIcon = ToolTipIcon.Warning }; public override bool OnMouseEnter(Glyph g) { MyGlyph glyph = (MyGlyph)g; if (!glyph.Control.Visible) return false; lock(ToolTip) ToolTip.Show(GetText(glyph), glyph.Control, glyph.Control.PointToClient(Control.MousePosition), 2000); return true; } public override bool OnMouseLeave(Glyph g) { lock (ToolTip) ToolTip.Hide(((MyGlyph)g).Control); return true; } private static string GetText(MyGlyph glyph) { return string.Format("{0} has {1} conflicts!", glyph.Control.Name, glyph.Issues); } }

Las anulaciones se llaman cuando el mouse ingresa / sale de los Bounds devueltos por la implementación de MyGlyph .

4. Resultados

Finalmente muestro captura de pantalla de un resultado de ejemplo. Dado que esto fue hecho por la implementación real, la información sobre herramientas es un poco más avanzada. El botón está desalineado en todos los cuadros combinados, porque está demasiado a la izquierda:

Gracias de nuevo a Ivan Stoev por indicarme la solución correcta. Espero poder dejar claro cómo lo implementé.


Utilice el método System.Drawing.Graphics.FromHwnd, pasando el HWND para la ventana del diseñador.

Obtenga el HWND profundizando en las manijas de la ventana para el estudio visual, a través de pinvoke . Quizás utilice herramientas como Inspect para encontrar classes ventanas y otra información que pueda ayudarlo a identificar la ventana correcta (del diseñador).

He escrito un programa de C # para que comiences here .