52

在 WPF 中创建 UserControl 时,我发现给它一些任意的高度和宽度值很方便,这样我就可以在 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>
4

9 回答 9

81

对于 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 设计器而言,您的技术就是一切。这就是我不使用 Visual Studio 设计器的原因。;)

于 2008-09-16T18:36:06.220 回答
39

在 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 属性,您将其设置为该值。

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

希望有帮助。

于 2008-09-16T18:44:07.230 回答
9

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

它列出了 Designer 中可用的所有值,d:例如d:DesignHeightd:DesignWidth、和其他几个值。d:IsDesignTimeCreatabled:CreateList

于 2011-04-03T00:26:31.547 回答
7

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

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

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

于 2008-09-17T01:57:35.177 回答
2

我一直在寻找类似于 Blend 中使用的解决方案,并且根据您的提及,我创建了带有两个附加属性 Width 和 Height 的简单行为类,这些属性仅在 DesinTime 中应用

公共静态类 DesignBehavior
{
    私有静态只读类型 OwnerType = typeof (DesignBehavior);

    #区域宽度

    公共静态只读 DependencyProperty WidthProperty =
        DependencyProperty.RegisterAttached(
            “宽度”,
            类型(双),
            所有者类型,
            new FrameworkPropertyMetadata(double.NaN, new PropertyChangedCallback(WidthChangedCallback)));

    公共静态双GetWidth(DependencyObject depObj)
    {
        返回(双)depObj.GetValue(宽度属性);
    }

    公共静态无效SetWidth(DependencyObject depObj,双值)
    {
        depObj.SetValue(宽度属性,值);
    }

    私有静态 void WidthChangedCallback(DependencyObject depObj,DependencyPropertyChangedEventArgs e)
    {
        如果(DesignerProperties.GetIsInDesignMode(depObj)){
            depObj.SetValue(FrameworkElement.WidthProperty, e.NewValue);
        }
    }

    #endregion

    #region 高度

    公共静态只读 DependencyProperty HeightProperty =
        DependencyProperty.RegisterAttached(
            “高度”,
            类型(双),
            所有者类型,
            new FrameworkPropertyMetadata(double.NaN, new PropertyChangedCallback(HeightChangedCallback)));

    公共静态双GetHeight(DependencyObject depObj)
    {
        返回(双)depObj.GetValue(高度属性);
    }

    公共静态无效SetHeight(DependencyObject depObj,双值)
    {
        depObj.SetValue(高度属性,值);
    }


    私有静态无效HeightChangedCallback(DependencyObject depObj,DependencyPropertyChangedEventArgs e)
    {
        如果(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-命名空间:ExtendedDataGrid.Behaviors"
    b:DesignBehavior.Width="600" b:DesignBehavior.Height="200">
    <网格>
         ...
    </网格>
</用户控制>
于 2011-05-06T09:18:51.433 回答
1

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

于 2012-08-29T01:56:16.243 回答
0

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

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

你怎么看?

于 2008-11-22T23:21:38.227 回答
0

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

If LicenseManager.UsageMode <> LicenseUsageMode.Designtime Then
    Me.Width = Double.NaN
    Me.Height = Double.NaN
End If
于 2009-01-07T19:58:31.470 回答
0

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

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

埃斯卡,

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

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

    ...
}

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

于 2009-07-30T17:30:21.047 回答