it-swarm-ru.tech

WPF UserControl Design Time Размер

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

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

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

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

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

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

<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>
50
Joseph Sturtevant

В Visual Studio добавьте атрибут Width и Height в свой UserControl XAML, но в коде вставьте этот

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

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

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

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

38
Alex Duggleby

Для Blend малоизвестный трюк - добавить эти атрибуты в ваш usercontrol или окно:

 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 соответственно. Однако это будет работать только для дизайнера смеси. Не дизайнер Visual Studio.

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

78
Brian Leahy

Вот список Атрибуты времени разработки в конструкторе Silverlight . Они одинаковы для дизайнера WPF.

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

8
CLaRGe

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

то есть: <loc:UserControl1 Width="auto" Height="auto" />

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

6
AndyL

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

 открытый статический класс DesignBehavior 
 {
 закрытая статическая только для чтения Тип 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, двойное значение) 
 {
 DepObj.SetValue (WidthProperty, значение ); 
} 
 
 частный статический void WidthChangedCallback (DependencyObject depObj, DependencyPropertyChangedEventArgs e) 
 {
 if (DesignerPropertie) s.GetIsInDesignMode (depObj)) {
 depObj.SetValue (FrameworkElement.WidthProperty, e.NewValue); 
} 
} 
 
 #endregion 
 
 #region Height 
 
 public static readonly DependencyProperty HeightProperty = 
 DependencyProperty.RegisterAttached (
 "Высота", 
 typeof (double), 
 OwnerType, 
 new FrameworkPropertyMetadata (double.NaN, new PropertyChangedCallback (HeightChangedCallback))); 
 
 публичная статическая переменная double GetHeight (DependencyObject) depObj) 
 {
 return (double) depObj.GetValue (HeightProperty); 
} 
 
 публичная статическая пустота SetHeight (DependencyObject depObj, двойное значение ) 
 {
 depObj.SetValue (HeightProperty, value); 
} 
 
 
 частный статический void HeightChangedCallback (DependencyObject depObj, DependencyPropertyChangedEven tArgs e) 
 {
 if (DesignerProperties.GetIsInDesignMode (depObj)) {
 depObj.SetValue (FrameworkElement.HeightProperty, e.NewValue); 
} 
} 
 
 #endregion 
 
} 

Затем в вашем UserControl вы просто устанавливаете эти свойства в 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
Ondrej

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

1
Roger Dufresne

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

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

esskar,

Я просто хочу добавить, что вы должны всегда вызывать метод base при переопределении метода "On".

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

    ...
}

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

0
jpierson

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

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

что ты думаешь?

0
esskar

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

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