WPF UserControl Design Time Размер - PullRequest
50 голосов
/ 16 сентября 2008

Создавая 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>

Ответы [ 9 ]

78 голосов
/ 16 сентября 2008

Для 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. ;)

38 голосов
/ 16 сентября 2008

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

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

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

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

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

8 голосов
/ 03 апреля 2011

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

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

6 голосов
/ 17 сентября 2008

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

т.е.: <loc:UserControl1 Width="auto" Height="auto" />

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

2 голосов
/ 06 мая 2011

Я искал похожее решение, подобное тому, которое использовалось в Blend, и с вашими упоминаниями я создал простой класс поведения с двумя прикрепленными свойствами Width & Height, которые применяются только в 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

}

Тогда в вашем 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>
1 голос
/ 29 августа 2012

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

0 голосов
/ 30 июля 2009

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

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

esskar,

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

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

    ...
}

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

0 голосов
/ 07 января 2009

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

If LicenseManager.UsageMode <> LicenseUsageMode.Designtime Then
    Me.Width = Double.NaN
    Me.Height = Double.NaN
End If
0 голосов
/ 23 ноября 2008

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...