WPF 用户控件设计时间大小

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/75495/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 19:36:51  来源:igfitidea点击:

WPF UserControl Design Time Size

wpfuser-controlsautosize

提问by Joseph Sturtevant

When creating a UserControl in WPF, I find it convenient to give it some arbitrary Height and Width values so that I can view my changes in the Visual Studio designer. When I run the control, however, I want the Height and Width to be undefined, so that the control will expand to fill whatever container I place it in. How can I acheive this same functionality without having to remove the Height and Width values before building my control? (Or without using DockPanel in the parent container.)

在 WPF 中创建 UserControl 时,我发现给它一些任意的 Height 和 Width 值很方便,以便我可以在 Visual Studio 设计器中查看我的更改。但是,当我运行控件时,我希望 Height 和 Width 是未定义的,以便控件将扩展以填充我放置它的任何容器。 如何在不必删除 Height 和 Width 值之前实现相同的功能建立我的控制?(或者在父容器中不使用 DockPanel。)

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 definition of UserControl1displays reasonably at design time but displays as a fixed size at run time:

以下定义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>

The following definition of UserControl1displays as a dot at design time but expands to fill the parent Window1at run time:

以下定义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>

采纳答案by Alex Duggleby

In Visual Studio add the Width and Height attribute to your UserControl XAML, but in the code-behind insert this

在 Visual Studio 中,将 Width 和 Height 属性添加到您的 UserControl XAML,但在代码隐藏中插入此

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

This checks to see if the control is running 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 it to if you remove the Width and Height attributes in XAML.

这将检查控件是否在设计模式下运行。如果不是(即运行时),它会将 Width 和 Height 设置为 NaN(不是数字),如果您删除 XAML 中的 Width 和 Height 属性,它就是您设置的值。

So at design-time you will have the preset width and height (including if you put the user control in a form) and at runtime it will dock depending on its parent container.

因此,在设计时,您将拥有预设的宽度和高度(包括是否将用户控件放入表单中),并且在运行时它将根据其父容器停靠。

Hope that helps.

希望有帮助。

回答by Brian Leahy

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

对于 Blend,一个鲜为人知的技巧是将这些属性添加到您的用户控件或窗口:

 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 design height and width to 500 and 600 respectively. However this will only work for the blend designer. Not the Visual Studio Designer.

这会将设计高度和宽度分别设置为 500 和 600。但是,这仅适用于混合设计器。不是 Visual Studio 设计器。

As far as the Visual Studio Designer your technique is all that works. Which is why I don't use the Visual Studio Designer. ;)

就 Visual Studio 设计器而言,您的技术就是一切。这就是我不使用 Visual Studio 设计器的原因。;)

回答by CLaRGe

Here are a list of Design-Time Attributes in the Silverlight Designer. They are the same for the WPF designer.

下面是Silverlight 设计器中的设计时属性列表。对于 WPF 设计器,它们是相同的。

It lists all of the d:values available in the Designer such as d:DesignHeight, d:DesignWidth, d:IsDesignTimeCreatable, d:CreateListand several others.

它列出了所有的d:值,在设计,如可用d:DesignHeightd:DesignWidthd:IsDesignTimeCreatabled:CreateList和其他几个人。

回答by AndyL

I do this all the time. Simply set the width and height values to "auto" where you instantiate your control, and this will override the design-time values for that UserControl.

我一直这样做。只需在实例化控件的位置将宽度和高度值设置为“自动”,这将覆盖该 UserControl 的设计时值。

ie: <loc:UserControl1 Width="auto" Height="auto" />

IE: <loc:UserControl1 Width="auto" Height="auto" />

Another option is to set a combination of MinWidth and MinHeight to a size that allows design-time work, while Width and Height remain "auto". Obviously, this only works if you don't need the UserControl to size smaller than the min values at runtime.

另一种选择是将 MinWidth 和 MinHeight 的组合设置为允许设计时工作的大小,而 Width 和 Height 保持“自动”。显然,这仅在您不需要 UserControl 的大小小于运行时的最小值时才有效。

回答by Ondrej

I was looking for similar solution like the one used in Blend and with your mentions I created simple behavior class with two attached properties Width & Height that are applied only in DesinTime

我一直在寻找类似于 Blend 中使用的解决方案,并且在您提到的情况下,我创建了简单的行为类,其中包含两个仅在 DesinTime 中应用的附加属性 Width 和 Height

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 中,您只需在 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>

回答by Roger Dufresne

Use MinWidth and MinHeight on the control. That way, you'll see it in the designer, and at runtime it will size the way you want.

在控件上使用 MinWidth 和 MinHeight。这样,您将在设计器中看到它,并在运行时按照您想要的方式调整大小。

回答by Roger Dufresne

I do it similar, but my solution assures that if you add your control to an container in design mode, it will appear reasonably.

我做的类似,但我的解决方案确保如果您在设计模式下将控件添加到容器中,它会合理显示。

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

what do you think?

你怎么看?

回答by Paul

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

感谢此解决方案的原始回答者!对于那些感兴趣的人,这是在VB中:

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

回答by jpierson

Some have suggested using the LicenseManager.UsageMode property which I've never seen before but I have used the following code.

有些人建议使用我以前从未见过的 LicenseManager.UsageMode 属性,但我使用了以下代码。

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

esskar,

埃斯卡,

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

我只想补充一点,在覆盖“On”方法时,您通常应该始终调用基类的方法。

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

    ...
}

Great workaround by the way, I'm using it myself now too.

顺便说一句,很好的解决方法,我现在也在使用它。