WPFでUserControlを作成するとき、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>
Visual Studioで、UserControl XAMLにWidth属性とHeight属性を追加しますが、コードビハインドにこれを挿入します
public UserControl1()
{
InitializeComponent();
if (LicenseManager.UsageMode != LicenseUsageMode.Designtime)
{
this.Width = double.NaN; ;
this.Height = double.NaN; ;
}
}
これにより、コントロールがデザインモードで実行されているかどうかが確認されます。そうでない場合(つまり、ランタイム)、XAMLでWidthおよびHeight属性を削除した場合に設定した値であるNaN(非数値)にWidthおよびHeightを設定します。
そのため、設計時にはプリセットの幅と高さ(フォームにユーザーコントロールを配置する場合を含む)があり、実行時には親コンテナーに応じてドッキングされます。
お役に立てば幸いです。
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 Designerではありません。
Visual Studio Designerに関しては、あなたのテクニックがすべて機能します。 Visual Studio Designerを使用しないのはこのためです。 ;)
Silverlightデザイナのデザイン時属性 のリストを次に示します。 WPFデザイナーにとっても同じです。
d:
、d:DesignHeight
、d:DesignWidth
、d:IsDesignTimeCreatable
など、Designerで使用可能なすべてのd:CreateList
値がリストされます。
私はいつもこれをしています。コントロールをインスタンス化する場所で幅と高さの値を「自動」に設定するだけで、そのユーザーコントロールのデザイン時の値が上書きされます。
すなわち:<loc:UserControl1 Width="auto" Height="auto" />
もう1つのオプションは、MinWidthとMinHeightの組み合わせを、設計時の作業が可能なサイズに設定する一方で、WidthとHeightを「自動」のままにすることです。明らかに、これは、実行時の最小値よりも小さいサイズにUserControlを必要としない場合にのみ機能します。
Blendで使用されるものと同様のソリューションを探していましたが、あなたの言及で、DesiTimeにのみ適用される2つの添付プロパティ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、 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(DesignerPropertie s.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、 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>
コントロールでMinWidthとMinHeightを使用します。そうすれば、デザイナーでそれを見ることができ、実行時にそれはあなたが望むようにサイズを調整します。
LicenseManager.UsageModeプロパティを使用することを提案した人もいますが、これは今まで見たことがないのですが、次のコードを使用しました。
if(!DesignerProperties.GetIsInDesignMode(this))
{
this.Width = double.NaN;
this.Height = double.NaN;
}
esskar、
「On」メソッドをオーバーライドする場合、通常は常にベースのメソッドを呼び出す必要があることを付け加えます。
protected override void OnVisualParentChanged(DependencyObject oldParent)
{
base.OnVisualParentChanged(oldParent);
...
}
ところで、素晴らしい回避策は、私も今自分で使っています。
私はそれを同様に行いますが、私のソリューションは、デザインモードでコンテナにコントロールを追加すると、合理的に表示されることを保証します。
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