关于用户控件:WPF用户控件设计时间大小

关于用户控件:WPF用户控件设计时间大小

WPF UserControl Design Time Size

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

以下代码演示了该问题:

1
2
3
4
5
6
7
8
9
<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的以下定义在设计时合理显示,但在运行时显示为固定大小:

1
2
3
4
5
6
<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

1
2
3
4
5
<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,一个鲜为人知的技巧是将这些属性添加到用户控件或窗口中:

1
2
3
4
 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中,但是在后面的代码中插入

1
2
3
4
5
6
7
8
9
public UserControl1()
{
    InitializeComponent();
    if (LicenseManager.UsageMode != LicenseUsageMode.Designtime)
    {
        this.Width = double.NaN; ;
        this.Height = double.NaN; ;
    }
}

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

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

希望有帮助。


这是Silverlight设计器中的设计时属性列表。对于WPF设计者来说,它们是相同的。

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


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

即:

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


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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
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中设置这些属性

1
2
3
4
5
6
7
8
9
10
<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>

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


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

1
2
3
4
5
if(!DesignerProperties.GetIsInDesignMode(this))
{
    this.Width = double.NaN;
    this.Height = double.NaN;
}

埃斯卡,

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

1
2
3
4
5
6
protected override void OnVisualParentChanged(DependencyObject oldParent)
{
    base.OnVisualParentChanged(oldParent);

    ...
}

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


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

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

我做类似的事情,但是我的解决方案确保了,如果您在设计模式下将控件添加到容器中,它将看起来很合理。

1
2
3
4
5
6
7
8
protected override void OnVisualParentChanged(DependencyObject oldParent)
{
    if (this.Parent != null)
    {
       this.Width = double.NaN;
       this.Height = double.NaN;
    }
}

你怎么看?


推荐阅读

    linux命令自动填充?

    linux命令自动填充?,培训,企业,教育,实战,基础,技术,项目,服务,环境,发展,哪

    脚本linux上运行命令?

    脚本linux上运行命令?,工具,代码,时间,密码,系统,环境,名字,位置,第三,下来,t

    linux运行脚本的命令?

    linux运行脚本的命令?,系统,工具,代码,服务,脚本,状态,密码,环境,位置,暂停,l

    linux命令行运行中断?

    linux命令行运行中断?,连续,工作,系统,信息,程序,命令,设备,工具,网络,情况,L

    vim运行linux命令?

    vim运行linux命令?,系统,工作,信息,地址,命令,标准,时间,情况,工具,基础,linu

    linux下并行运行命令?

    linux下并行运行命令?,系统,服务,工作,命令,环境,网络,暂停,文件,脚本,参数,l

    jar运行命令linux?

    jar运行命令linux?,项目,系统,平台,工具,上期,命令,选项,日志,文件名,目录,Li

    jar运行命令linux?

    jar运行命令linux?,项目,系统,平台,工具,上期,命令,选项,日志,文件名,目录,Li

    linux下并行运行命令?

    linux下并行运行命令?,系统,服务,工作,命令,环境,网络,暂停,文件,脚本,参数,l

    linux命令行后台运行?

    linux命令行后台运行?,服务,状态,标准,暂停,命令,后台,连续,地方,工作,方法,l

    脚本运行linux命令?

    脚本运行linux命令?,系统,环境,工具,工作,位置,底部,代码,发行,官网,终端,lin

    linux进程运行命令?

    linux进程运行命令?,系统,工作,状态,地址,信息,进程,基础,命令,管理,软件,lin

    linux显示运行命令?

    linux显示运行命令?,系统,服务,状态,信息,工具,数据,电脑,标准,管理,时间,如

    linux运行vim命令?

    linux运行vim命令?,系统,工具,官方网站,模式,基础,数据,代码,环境,入口,命令

    linux监控命令运行?

    linux监控命令运行?,系统,工作,地址,信息,工具,情况,标准,环境,命令,状态,lin

    linux中命令停止运行?

    linux中命令停止运行?,系统,代码,第一,命令,进程,指令,程序,方法,接线,硬盘,l

    linux自动运行命令?

    linux自动运行命令?,服务,系统,时间,代码,周期性,第一,命令,管理,在线,状态,l

    linux开启运行命令?

    linux开启运行命令?,系统,服务,工作,管理,状态,命令,标准,情况,环境,工具,lin

    linux运行wps命令?

    linux运行wps命令?,软件,官网,名称,时间,电脑,系统,工具,环境,项目,数据,wps