WPF UserControl Design Time Taille

Lors de la création d’un UserControl dans WPF, je trouve pratique de lui atsortingbuer des valeurs de hauteur et de largeur arbitraires pour pouvoir visualiser mes modifications dans le concepteur de Visual Studio. Lorsque je lance le contrôle, toutefois, je souhaite que la hauteur et la largeur ne soient pas définies, afin que le contrôle se développe pour remplir le conteneur dans lequel il est placé. construire mon contrôle? (Ou sans utiliser DockPanel dans le conteneur parent.)

Le code suivant illustre le problème:

     

La définition suivante de UserControl1 s’affiche raisonnablement au moment de la conception mais affiche une taille fixe au moment de l’exécution:

    

La définition suivante de UserControl1 s’affiche sous la forme d’un point au moment de la conception, mais se développe pour remplir le parent Window1 au moment de l’exécution:

    

Dans Visual Studio, ajoutez l’atsortingbut Largeur et Hauteur à votre fichier UserControl XAML, mais insérez-le dans le code-behind.

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

Cela vérifie si le contrôle s’exécute en mode Design. Si ce n’est pas le cas (c.-à-d. Runtime), la largeur et la hauteur seront définies sur NaN (pas un nombre), c’est-à-dire la valeur que vous définissez si vous supprimez les atsortingbuts Largeur et Hauteur dans XAML.

Ainsi, au moment de la conception, vous disposerez de la largeur et de la hauteur prédéfinies (y compris si vous placez le contrôle utilisateur dans un formulaire) et lors de l’exécution, elles seront ancrées en fonction de leur conteneur parent.

J’espère que cela pourra aider.

Pour Blend, un truc peu connu consiste à append ces atsortingbuts à votre contrôle utilisateur ou à votre fenêtre:

  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" 

Cela définira la hauteur et la largeur du design à 500 et 600 respectivement. Cependant, cela ne fonctionnera que pour le concepteur de mixage. Pas le concepteur de Visual Studio.

En ce qui concerne Visual Studio Designer, votre technique est tout ce qui fonctionne. C’est pourquoi je n’utilise pas Visual Studio Designer. 😉

Voici une liste des atsortingbuts au moment du design dans le concepteur Silverlight . Ils sont les mêmes pour le concepteur WPF.

Il répertorie toutes les valeurs d: disponibles dans Designer, telles que d:DesignHeight , d:DesignWidth , d:IsDesignTimeCreatable , d:CreateList et plusieurs autres.

Je fais ça tout le temps. Il suffit de définir les valeurs de largeur et de hauteur sur “auto” où vous instanciez votre contrôle, ce qui remplacera les valeurs de conception de ce contrôle utilisateur.

ie:

Une autre option consiste à définir une combinaison de MinWidth et de MinHeight sur une taille permettant un travail au moment du design, tandis que la largeur et la hauteur restnt “auto”. De toute évidence, cela ne fonctionne que si vous n’avez pas besoin que UserControl soit plus petit que les valeurs min à l’exécution.

Je cherchais une solution similaire à celle utilisée dans Blend et avec vos mentions j’ai créé une classe de comportement simple avec deux propriétés attachées Width & Height qui ne sont appliquées que dans DesinTime

 classe statique publique DesignBehavior 
 {
     private static readonly Type OwnerType = typeof (DesignBehavior);

     Largeur de la région

     public static readonly DependencyProperty WidthProperty =
         DependencyProperty.RegisterAttached (
             "Largeur",
             typeof (double),
             OwnerType,
             new FrameworkPropertyMetadata (double.NaN, new PropertyChangedCallback (WidthChangedCallback)));

     double statique statique GetWidth (DependencyObject depObj)
     {
         return (double) depObj.GetValue (WidthProperty);
     }

     statique statique vide SetWidth (DependencyObject depObj, double valeur)
     {
         depObj.SetValue (WidthProperty, valeur);
     }

     vide statique privé WidthChangedCallback (DependencyObject depObj, DependencyPropertyChangedEventArgs e)
     {
         if (DesignerProperties.GetIsInDesignMode (depObj)) {
             depObj.SetValue (FrameworkElement.WidthProperty, e.NewValue);
         }
     }

     #endregion

     Hauteur de la région

     public static readonly DependencyProperty HeightProperty =
         DependencyProperty.RegisterAttached (
             "La taille",
             typeof (double),
             OwnerType,
             nouveau FrameworkPropertyMetadata (double.NaN, new PropertyChangedCallback (HeightChangedCallback)));

     double statique public GetHeight (DependencyObject depObj)
     {
         return (double) depObj.GetValue (HeightProperty);
     }

     statique statique vide SetHeight (DependencyObject depObj, valeur double)
     {
         depObj.SetValue (HeightProperty, valeur);
     }


     private static void HeightChangedCallback (DependencyObject depObj, DependencyPropertyChangedEventArgs e)
     {
         if (DesignerProperties.GetIsInDesignMode (depObj)) {
             depObj.SetValue (FrameworkElement.HeightProperty, e.NewValue);
         }
     }

     #endregion

 }

Ensuite, dans votre UserControl, vous venez de définir ces propriétés dans Xaml

 
     
          ...
     
 

Utilisez MinWidth et MinHeight sur le contrôle. De cette façon, vous le verrez dans le concepteur, et lors de l’exécution, il dimensionnera comme vous le souhaitez.

Je le fais de manière similaire, mais ma solution garantit que si vous ajoutez votre contrôle à un conteneur en mode conception, il apparaîtra raisonnablement.

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

Qu’est-ce que tu penses?

Merci au répondeur original pour cette solution! Pour ceux qui sont intéressés, la voici en VB:

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

Certains ont suggéré d’utiliser la propriété LicenseManager.UsageMode que je n’avais jamais vue auparavant, mais j’ai utilisé le code suivant.

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

esskar,

Je veux juste append que vous devez généralement toujours appeler la méthode de la base lors du remplacement d’une méthode “On”.

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

Super solution de contournement au passage, je l’utilise moi aussi maintenant.