【问题标题】:WPF UserControl Design Time SizeWPF 用户控件设计时间大小
【发布时间】:2008-09-16 18:32:10
【问题描述】:

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

【问题讨论】:

    标签: wpf user-controls autosize


    【解决方案1】:

    对于 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 设计器的原因。 ;)

    【讨论】:

    • 不幸的是,这会导致 Visual Studio 设计器根本不呈现内容:(
    • 哦...我不会用,我会改答案
    • 这不再是把戏。 VS2012 将为新的空 UserControl 创建该解决方案!
    【解决方案2】:

    在 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 属性,它就是您设置的值。

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

    希望对您有所帮助。

    【讨论】:

    • 这可以用相反的方式完成吗?也就是说,我可以让用户控件 XAML 高度/宽度未定义,然后仅在 LicenseManager.UsageMode == LicenseUsageMode.Designtime 时在构造函数中设置高度和宽度吗?
    • 很遗憾,LicenseUsageMode 不包含设计时间。
    【解决方案3】:

    这里是Design-Time Attributes in the Silverlight Designer 的列表。对于 WPF 设计器,它们是相同的。

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

    【讨论】:

      【解决方案4】:

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

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

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

      【讨论】:

        【解决方案5】:

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

        公共静态类 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 中设置这些属性

        ... 网格> 用户控制>

        【讨论】:

          【解决方案6】:

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

          【讨论】:

            【解决方案7】:

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

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

            你怎么看?

            【讨论】:

            • 如果您打算将remeber 覆盖到案例库。 base.OnVisualParentChanged(oldParent);
            【解决方案8】:

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

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

            【讨论】:

              【解决方案9】:

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

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

              埃斯卡,

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

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

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

              【讨论】:

              • 请注意,此解决方案以及迄今为止提供的其他解决方案都不能解决在另一个控件中使用此控件属性并且在设计器中查看该控件时显示该控件属性的问题。希望新的 DesignHeight 和 DesignWidth 属性能够解决这个问题,这是 Visual Studio 2010。
              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2012-04-03
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多