Размер времени разработки пользовательского интерфейса WPF

При создании UserControl в WPF мне удобно давать некоторые произвольные значения Height и Width, чтобы я мог просматривать мои изменения в дизайнере Visual Studio. Однако, когда я запускаю элемент управления, я хочу, чтобы высота и ширина были неопределенными, так что элемент управления будет расширяться, чтобы заполнить любой контейнер, в который я его помещаю. Как я могу получить эту же функциональность, не удаляя значения высоты и ширины перед строит мой контроль? (Или без использования DockPanel в родительском контейнере.)

Следующий код демонстрирует проблему:

     

Следующее определение UserControl1 отображает разумно во время разработки, но отображается как фиксированный размер во время выполнения:

    

Следующее определение UserControl1 отображается как точка во время разработки, но расширяется, чтобы заполнить родительский Window1 во время выполнения:

    

В Visual Studio добавьте атрибут «Ширина и высота» в ваш UserControl XAML, но в коде вставьте это

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

Это проверяет, работает ли элемент управления в режиме разработки. Если нет (т. Е. Время выполнения), он установит ширину и высоту в NaN (не число), которое является значением, которое вы установили, если вы удаляете атрибуты Ширина и Высота в XAML.

Таким образом, во время разработки вы будете иметь заданную ширину и высоту (в том числе, если вы поместите пользовательский элемент управления в форму), и во время выполнения он будет состыкован в зависимости от своего родительского контейнера.

Надеюсь, это поможет.

Для Blend малоизвестный трюк заключается в том, чтобы добавить эти атрибуты в ваш usercontrol или 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" 

Это установит высоту и ширину дизайна до 500 и 600 соответственно. Однако это будет работать только для дизайнера blend. Не Visual Studio Designer.

Что касается Visual Studio Designer, то ваша техника – это все, что работает. Вот почему я не использую Visual Studio Designer. 😉

Ниже приведен список атрибутов Design-Time в Silverlight Designer . Они одинаковы для дизайнера WPF.

В нем перечислены все значения d: доступные в конструкторе, такие как d:IsDesignTimeCreatable , d:CreateList , d:IsDesignTimeCreatable , d:CreateList и несколько других.

Я все время это делаю. Просто установите значения ширины и высоты на «авто», где вы создаете экземпляр своего элемента управления, и это переопределит значения времени разработки для этого UserControl.

т.е.:

Другой вариант – установить комбинацию MinWidth и MinHeight на размер, который позволяет работать с временем разработки, а ширина и высота остаются «авто». Очевидно, что это работает, только если вам не нужен размер UserControl, размер которого меньше минимальных значений во время выполнения.

Я искал аналогичное решение, подобное тому, которое используется в Blend, и с вашими упоминаниями я создал простой class поведения с двумя прикрепленными свойствами Width & Height, которые применяются только в DesinTime

 открытый статический class DesignBehavior 
 {
     private static readonly Тип OwnerType = typeof (DesignBehavior);

     #region Ширина

     public static readonly DependencyProperty WidthProperty =
         DependencyProperty.RegisterAttached (
             "Ширина",
             typeof (double),
             OwnerType,
             new FrameworkPropertyMetadata (double.NaN, новый PropertyChangedCallback (WidthChangedCallback)));

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

     public static void SetWidth (DependencyObject depObj, двойное значение)
     {
         depObj.SetValue (WidthProperty, значение);
     }

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

     #endregion

     #region Высота

     public static readonly DependencyProperty HeightProperty =
         DependencyProperty.RegisterAttached (
             "Высота",
             typeof (double),
             OwnerType,
             new FrameworkPropertyMetadata (double.NaN, новый PropertyChangedCallback (HeightChangedCallback)));

     открытый статический двойной GetHeight (DependencyObject depObj)
     {
         return (double) depObj.GetValue (HeightProperty);
     }

     public static void SetHeight (DependencyObject depObj, двойное значение)
     {
         depObj.SetValue (HeightProperty, value);
     }


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

     #endregion

 }

Затем в вашем UserControl вы просто установите эти свойства в Xaml

 
     
          ...
     
 

Используйте MinWidth и MinHeight на элементе управления. Таким образом, вы увидите его в дизайнере, и во время выполнения он будет таким же, как вы хотите.

Я делаю это похоже, но мое решение гарантирует, что если вы добавите свой контроль в контейнер в режиме разработки, он будет выглядеть разумно.

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

что вы думаете?

Благодаря оригинальному ответчику для этого решения! Для тех, кого это интересует, вот он в VB:

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

Некоторые предложили использовать свойство LicenseManager.UsageMode, которое я никогда раньше не видел, но я использовал следующий код.

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

esskar,

Я просто хочу добавить, что вы обычно должны всегда вызывать метод базы при переопределении метода «Вкл».

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

К большому обходному пути я тоже использую его сейчас.

  • почему установка ScrollViewer.CanContentScroll в false отключает виртуализацию
  • Закрыть окно из ViewModel
  • Как создать таймер в WPF?
  • Как преобразовать размер WPF в физические пиксели?
  • ItemsControl с горизонтальной ориентацией
  • Что делает InitializeComponent () и как он работает в WPF?
  • Как открыть всплывающее окно WPF при нажатии другого элемента управления, используя только разметку XAML?
  • Как вы успешно реализовали функцию MessageBox.Show () в MVVM?
  • WPF загружает анимацию в отдельный stream пользовательского интерфейса? (С #)
  • Как повысить свойства Измененные события в зависимости от свойства?
  • WPF TabControl - предотrotation разгрузки при изменении вкладки?
  • Давайте будем гением компьютера.