WPF UserControl设计时间大小

时间:2020-03-05 18:56:47  来源:igfitidea点击:

在WPF中创建UserControl时,我发现为它提供一些任意的Height和Width值很方便,这样我就可以在Visual Studio设计器中查看更改。但是,当我运行控件时,我希望未定义Height和Width,以便控件可以展开以填充放置它的任何容器。如何实现相同的功能而不必先删除Height和Width值建立我的控制权? (或者不使用父容器中的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>

解决方案

回答

对于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"

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

就Visual Studio Designer而言,技术就是行之有效的。这就是为什么我不使用Visual Studio Designer的原因。 ;)

回答

在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(不是数字),这是我们在XAML中删除Width和Height属性时设置的值。

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

希望能有所帮助。

回答

我一直都这样做。只需在实例化控件的地方将width和height值设置为" auto",就会覆盖该UserControl的设计时值。

即:&lt;loc:UserControl1 Width =" auto" Height =" auto" />

另一种选择是将MinWidth和MinHeight的组合设置为允许设计时工作的大小,而Width和Height保持"自动"。显然,仅当我们不需要UserControl的大小小于运行时的min值时,此方法才有效。

回答

我做类似的事情,但是我的解决方案保证了,如果我们在设计模式下将控件添加到容器中,它就会显得合理。

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

埃斯卡,

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

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

    ...
}

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