wpf user-controls autosize

Tamaño de tiempo de diseño de WPF UserControl



user-controls autosize (9)

En Visual Studio, agregue el atributo Ancho y Altura a su UserControl XAML, pero en el código subyacente inserte este

public UserControl1() { InitializeComponent(); if (LicenseManager.UsageMode != LicenseUsageMode.Designtime) { this.Width = double.NaN; ; this.Height = double.NaN; ; } }

Esto verifica si el control se está ejecutando en modo de diseño. Si no (es decir, el tiempo de ejecución) establecerá el ancho y la altura en NaN (No es un número), que es el valor que establece si elimina los atributos de Ancho y Altura en XAML.

Por lo tanto, en tiempo de diseño tendrá el ancho y alto preestablecidos (incluso si pone el control de usuario en un formulario) y en tiempo de ejecución se acoplará dependiendo de su contenedor principal.

Espero que ayude.

Al crear un UserControl en WPF, me parece conveniente darle algunos valores arbitrarios de altura y ancho para que pueda ver mis cambios en el diseñador de Visual Studio. Sin embargo, cuando ejecuto el control, quiero que la altura y el ancho no estén definidos, de modo que el control se expandirá para llenar cualquier contenedor en el que lo coloque. ¿Cómo puedo lograr esta misma funcionalidad sin tener que eliminar los valores de altura y ancho antes? construyendo mi control? (O sin usar DockPanel en el contenedor principal).

El siguiente código demuestra el problema:

<Window x:Class="ExampleApplication3.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:loc="clr-namespace:ExampleApplication3" Title="Example" Height="600" Width="600"> <Grid Background="LightGray"> <loc:UserControl1 /> </Grid> </Window>

La siguiente definición de UserControl1 muestra razonablemente en el momento del diseño, pero se muestra como un tamaño fijo en tiempo de ejecución:

<UserControl x:Class="ExampleApplication3.UserControl1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Height="300" Width="300"> <Grid Background="LightCyan" /> </UserControl>

La siguiente definición de UserControl1 muestra como un punto en el momento del diseño, pero se expande para llenar la Window1 principal Window1 en el tiempo de ejecución:

<UserControl x:Class="ExampleApplication3.UserControl1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <Grid Background="LightCyan" /> </UserControl>


Para Blend, un truco poco conocido es agregar estos atributos a su usercontrol o ventana:

xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" d:DesignHeight="500" d:DesignWidth="600"

Esto establecerá la altura y el ancho del diseño en 500 y 600 respectivamente. Sin embargo, esto solo funcionará para el diseñador de mezclas. No es el Diseñador de Visual Studio.

En cuanto a Visual Studio Designer, tu técnica es lo único que funciona. Por eso no uso Visual Studio Designer. ;)


Hago esto todo el tiempo. Simplemente configure los valores de ancho y alto en "automático" donde crea una instancia de su control, y esto anulará los valores de tiempo de diseño para ese UserControl.

es decir: <loc:UserControl1 Width="auto" Height="auto" />

Otra opción es establecer una combinación de MinWidth y MinHeight con un tamaño que permita el trabajo en tiempo de diseño, mientras que Width y Height permanecen "automáticos". Obviamente, esto solo funciona si no necesita que UserControl tenga un tamaño inferior a los valores mínimos en tiempo de ejecución.


Lo hago de manera similar, pero mi solución asegura que si agrega su control a un contenedor en modo de diseño, aparecerá razonablemente.

protected override void OnVisualParentChanged(DependencyObject oldParent) { if (this.Parent != null) { this.Width = double.NaN; this.Height = double.NaN; } }

¿Qué piensas?


¡Gracias al respondedor original por esta solución! Para aquellos que están interesados, aquí está en VB:

If LicenseManager.UsageMode <> LicenseUsageMode.Designtime Then Me.Width = Double.NaN Me.Height = Double.NaN End If


Algunos han sugerido usar la propiedad LicenseManager.UsageMode que nunca he visto antes, pero he usado el siguiente código.

if(!DesignerProperties.GetIsInDesignMode(this)) { this.Width = double.NaN; this.Height = double.NaN; }

esskar,

Solo quiero agregar que generalmente siempre debes llamar al método de la base cuando anulas un método "Encendido".

protected override void OnVisualParentChanged(DependencyObject oldParent) { base.OnVisualParentChanged(oldParent); ... }

Gran solución por cierto, la estoy usando ahora también.


Estaba buscando una solución similar a la utilizada en Blend y con sus menciones creé una clase de comportamiento simple con dos propiedades adjuntas, Ancho y Alto, que se aplican solo en DesinTime.

public static class DesignBehavior { private static readonly Type OwnerType = typeof (DesignBehavior); #region Width public static readonly DependencyProperty WidthProperty = DependencyProperty.RegisterAttached( "Width", typeof (double), OwnerType, new FrameworkPropertyMetadata(double.NaN, new PropertyChangedCallback(WidthChangedCallback))); public static double GetWidth(DependencyObject depObj) { return (double)depObj.GetValue(WidthProperty); } public static void SetWidth(DependencyObject depObj, double value) { depObj.SetValue(WidthProperty, value); } private static void WidthChangedCallback(DependencyObject depObj, DependencyPropertyChangedEventArgs e) { if (DesignerProperties.GetIsInDesignMode(depObj)) { depObj.SetValue(FrameworkElement.WidthProperty, e.NewValue); } } #endregion #region Height public static readonly DependencyProperty HeightProperty = DependencyProperty.RegisterAttached( "Height", typeof (double), OwnerType, new FrameworkPropertyMetadata(double.NaN, new PropertyChangedCallback(HeightChangedCallback))); public static double GetHeight(DependencyObject depObj) { return (double)depObj.GetValue(HeightProperty); } public static void SetHeight(DependencyObject depObj, double value) { depObj.SetValue(HeightProperty, value); } private static void HeightChangedCallback(DependencyObject depObj, DependencyPropertyChangedEventArgs e) { if (DesignerProperties.GetIsInDesignMode(depObj)) { depObj.SetValue(FrameworkElement.HeightProperty, e.NewValue); } } #endregion }

Luego, en su UserControl, simplemente establece estas propiedades en Xaml

<UserControl x:Class="ExtendedDataGrid.Views.PersonOverviewView" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:tool="http://schemas.microsoft.com/wpf/2008/toolkit" xmlns:b="clr-namespace:ExtendedDataGrid.Behaviors" b:DesignBehavior.Width="600" b:DesignBehavior.Height="200"> <Grid> ... </Grid> </UserControl>


Use MinWidth y MinHeight en el control. De esta forma, lo verá en el diseñador, y en tiempo de ejecución tendrá el tamaño que desee.


Aquí hay una lista de Atributos de tiempo de diseño en Silverlight Designer . Son lo mismo para el diseñador de WPF.

Enumera todos los valores d: disponibles en el Diseñador, como d:DesignHeight , d:DesignWidth , d:IsDesignTimeCreatable , d:CreateList y muchos otros.