it-swarm.cn

WPF UserControl设计时间大小

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

在Visual Studio中,将“宽度”和“高度”属性添加到UserControl XAML,但在代码隐藏中插入此属性

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

这将检查控件是否在设计模式下运行。如果不是(即运行时),则将宽度和高度设置为NaN(非数字),如果删除XAML中的“宽度”和“高度”属性,则将其设置为值。

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

希望有所帮助。

38
Alex Duggleby

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

 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 Designer。

就Visual Studio Designer而言,您的技术是可行的。这就是我不使用Visual Studio Designer的原因。 ;)

78
Brian Leahy

以下是Silverlight Designer中的 Design-Time属性列表 。它们与WPF设计者相同。

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

8
CLaRGe

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

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

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

6
AndyL

我正在寻找类似于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,[。_____。]新的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(DesignerPropertie) s.GetIsInDesignMode(depObj)){[。_____。] depObj.SetValue(FrameworkElement.WidthProperty,e.NewValue); 
} 
} 
 
 #endregion 
 
#region高度
 
 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, DependencyPropertyChangedEven tArgs e)
 {[。_____。] if(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-namespace:ExtendedDataGrid.Behaviors”
 b:DesignBehavior.Width =“600”b:DesignBehavior.Height =“200”> 
 <Grid> 
 ...... 
 </ Grid> 
 </ UserControl> 
2
Ondrej

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

1
Roger Dufresne

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

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

esskar,

我只想补充一点,在覆盖“On”方法时,通常应该总是调用base的方法。

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

    ...
}

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

0
jpierson

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

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

你怎么看?

0
esskar

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

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