WPF UI Development Time Size

When creating UserControl in WPF, itโ€™s more convenient for me to give some arbitrary Height and Width values โ€‹โ€‹so that I can view my changes in the Visual Studio designer. However, when I launch the control, I want the height and width to be undefined, so the control will expand to fill any container that I put it in. How can I get the same functionality without removing the height and width of the values โ€‹โ€‹before building my control? (Or without using the DockPanel in the parent container.)

The following code demonstrates the problem:

<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> 

The following UserControl1 definition is displayed at design time, but displayed as a fixed size at run time:

 <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> 

The following UserControl1 definition appears as a dot at design time, but expands to populate parent Window1 at run time:

 <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> 
+49
wpf user-controls autosize
Sep 16 '08 at 18:32
source share
9 answers

In Visual Studio, add the Width and Height attribute to your UserControl XAML, but paste it into the code

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

This checks to see if the control is in design mode. If not (i.e. runtime), it will set the width and height to NaN (not a number), which is the value you set for this if you remove the Width and Height attributes in XAML.

Thus, at design time, you will have the specified width and height (including if you place the user control on the form), and at run time it will be docked depending on its parent container.

Hope this helps.

+38
Sep 16 '08 at 18:44
source share

For Blend, a little-known trick is to add these attributes to your user control or window:

  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" 

This will set the height and width of the design to 500 and 600, respectively. However, this will only work for the blend designer. Not Visual Studio Designer.

As for Visual Studio Designer, then your technique works. This is why I am not using Visual Studio Designer .;)

+78
Sep 16 '08 at 18:36
source share

Here is a list of design-time attributes in Silverlight Designer . They are the same for the WPF designer.

It lists all the d: values โ€‹โ€‹available in the constructor, such as d:DesignHeight , d:DesignWidth , d:IsDesignTimeCreatable , d:CreateList and several others.

+8
Apr 3 2018-11-11T00:
source share

I do this all the time. Just set the width and height values โ€‹โ€‹to "auto" where you create an instance of your control and this will override the design time values โ€‹โ€‹for this UserControl.

i.e.: <loc:UserControl1 Width="auto" Height="auto" />

Another option is to set the MinWidth and MinHeight combination to a size that allows you to work with development time, and the width and height remain "auto". Obviously, this only works if you don't need a UserControl size that is smaller than the minimum values โ€‹โ€‹at runtime.

+6
Sep 17 '08 at 1:57
source share

I was looking for a similar solution similar to the one used in Blend, and with your references, I created a simple behavior class with two attached Width and Height properties that apply only to 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

 }

Then in your UserControl you just set these properties in 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>
+2
May 6 '11 at 9:18
source share

Use MinWidth and MinHeight for the control. So you will see it in the designer, and at runtime it will be the same as you want.

+1
Aug 29 2018-12-12T00:
source share

I make it look like it, but my solution ensures that if you add your control to the container in development mode, it will look reasonable.

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

what do you think?

0
Nov 22 '08 at 23:21
source share

Thanks to the original responder for this solution! For those who are interested, here it is in VB:

 If LicenseManager.UsageMode <> LicenseUsageMode.Designtime Then Me.Width = Double.NaN Me.Height = Double.NaN End If 
0
Jan 07 '09 at 19:58
source share

Some suggested using the LicenseManager.UsageMode property, which I had never seen before, but I used the following code.

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

esskar,

I just want to add that you usually should always call the base method when overriding the "On" method.

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

The great workaround, by the way, I also use it myself.

0
Jul 30 '09 at 17:30
source share



All Articles