WPF グリッドの行または列のマージンやパディングを簡単に指定できますか?
もちろん、スペースを空けるために余分な列を追加することもできますが、これはパディング/マージンの仕事のようです ( XAMLがより単純になります)。この機能を追加するために標準のグリッドから派生した人はいますか?
RowDefinition
とColumnDefinition
はタイプContentElement
であり、Margin
厳密にはFrameworkElement
プロパティです。したがって、「それは簡単に可能ですか」というあなたの質問に対する答えは、最も明確なノーです。いいえ、この種の機能を示すレイアウト パネルは見たことがありません。
あなたが提案したように、余分な行または列を追加できます。Grid
ただし、要素自体、または の内部にあるものにマージンを設定することもできるGrid
ため、現時点ではそれが最善の回避策です。
Border
セル コントロールの外側のコントロールを使用し、そのパディングを定義します。
<Grid>
<Grid.Resources >
<Style TargetType="Border" >
<Setter Property="Padding" Value="5,5,5,5" />
</Style>
</Grid.Resources>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Border Grid.Row="0" Grid.Column="0">
<YourGridControls/>
</Border>
<Border Grid.Row="1" Grid.Column="0">
<YourGridControls/>
</Border>
</Grid>
ソース:
次のようなものを使用できます。
<Style TargetType="{x:Type DataGridCell}">
<Setter Property="Padding" Value="4" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridCell}">
<Border Padding="{TemplateBinding Padding}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
<ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
または、TemplateBindings が必要ない場合:
<Style TargetType="{x:Type DataGridCell}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridCell}">
<Border Padding="4">
<ContentPresenter />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
誰もまだ言及していないので、独自のソリューションを追加すると思いました。Grid に基づいて UserControl を設計する代わりに、スタイル宣言を使用してグリッドに含まれるコントロールをターゲットにすることができます。すべての要素にパディング/マージンを追加することを処理しますが、これは面倒で手間がかかります。たとえば、Grid に TextBlocks しか含まれていない場合、次のようにできます。
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Margin" Value="10"/>
</Style>
これは、「セルのパディング」に相当します。
GridWithMargin
から継承した独自のクラスを記述Grid
し、メソッドをオーバーライドしArrangeOverride
てマージンを適用できます。
最近、いくつかのソフトウェアを開発しているときにこの問題に遭遇しました。なぜ彼らはこんなことをしたのだろう…答えはすぐ目の前にあった。データの行はオブジェクトであるため、オブジェクト指向を維持する場合は、特定の行のデザインを分離する必要があります (後で行表示を再利用する必要があるとします)。そこで、ほとんどのデータ表示にデータバインド スタック パネルとカスタム コントロールを使い始めました。リストはときどき登場しますが、ほとんどの場合、グリッドは主要なページ構成 (ヘッダー、メニュー エリア、コンテンツ エリア、その他のエリア) にのみ使用されています。カスタム オブジェクトは、スタック パネルまたはグリッド内の各行の間隔要件を簡単に管理できます (単一のグリッド セルに行オブジェクト全体を含めることができます。これには、方向の変化に適切に反応するという追加の利点もあります。
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<custom:MyRowObject Style="YourStyleHereOrGeneralSetter" Grid.Row="0" />
<custom:MyRowObject Style="YourStyleHere" Grid.Row="1" />
</Grid>
また
<StackPanel>
<custom:MyRowObject Style="YourStyleHere" Grid.Row="0" />
<custom:MyRowObject Style="YourStyleHere" Grid.Row="1" />
</StackPanel>
データバインディングを使用している場合、カスタムコントロールはDataContextも継承します...このアプローチの私の個人的なお気に入りの利点。
私は自分のグリッドの1つで今それをしました。
1つの可能性は、探しているパディング/マージンとして機能する固定幅の行と列を追加することです。
また、コンテナーのサイズに制約されていること、およびグリッドが含まれている要素またはその指定された幅と高さと同じ大きさになることを考慮することもできます。幅や高さを設定せずに、単純に列と行を使用できます。そうすれば、デフォルトでグリッド内の合計スペースが均等に分割されます。次に、要素をグリッド内で垂直方向および水平方向に中央に配置するだけです。
もう 1 つの方法は、すべてのグリッド要素を固定サイズとマージンを持つ単一の行と列のグリッドでラップすることです。グリッドには、実際の要素を含む固定幅/高さのボックスが含まれていること。
前に述べたように、GridWithMargins クラスを作成します。ここに私の作業コードの例があります
public class GridWithMargins : Grid
{
public Thickness RowMargin { get; set; } = new Thickness(10, 10, 10, 10);
protected override Size ArrangeOverride(Size arrangeSize)
{
var basesize = base.ArrangeOverride(arrangeSize);
foreach (UIElement child in InternalChildren)
{
var pos = GetPosition(child);
pos.X += RowMargin.Left;
pos.Y += RowMargin.Top;
var actual = child.RenderSize;
actual.Width -= (RowMargin.Left + RowMargin.Right);
actual.Height -= (RowMargin.Top + RowMargin.Bottom);
var rec = new Rect(pos, actual);
child.Arrange(rec);
}
return arrangeSize;
}
private Point GetPosition(Visual element)
{
var posTransForm = element.TransformToAncestor(this);
var areaTransForm = posTransForm.Transform(new Point(0, 0));
return areaTransForm;
}
}
使用法:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApplication1"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<local:GridWithMargins ShowGridLines="True">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Rectangle Fill="Red" Grid.Row="0" Grid.Column="0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
<Rectangle Fill="Green" Grid.Row="1" Grid.Column="0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
<Rectangle Fill="Blue" Grid.Row="1" Grid.Column="1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
</local:GridWithMargins>
</Grid>
</Window>