WPF: 열/행 여백/패딩이 있는 그리드?
WPF 그리드에서 행 또는 열에 대한 여백 및/또는 패딩을 쉽게 지정할 수 있습니까?
물론 공간을 확보하기 위해 추가 열을 추가할 수도 있지만, 패딩/마진을 위한 작업인 것 같습니다(XAML이 훨씬 단순해질 것입니다).이 기능을 추가하기 위해 표준 그리드에서 파생된 사람이 있습니까?
RowDefinition
그리고.ColumnDefinition
이 형의유입니다.ContentElement
,그리고.Margin
는 엄하게는입니다.FrameworkElement
소유물.그래서 당신의 질문에 "그것이 쉽게 가능한가"라는 대답은 가장 확실한 거절입니다.아니요, 이런 종류의 기능을 보여주는 레이아웃 패널은 본 적이 없습니다.
제안한 대로 행 또는 열을 추가할 수 있습니다.은 러나마설수있다습니도할정을그진에 을 설정할 수도 .Grid
자체,▁that▁ 안에 들어갈 어떤 것이든.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>
또는 템플릿 바인딩이 필요하지 않은 경우:
<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>
아직 아무도 이것에 대해 언급하지 않았기 때문에 저만의 해결책을 추가하려고 생각했습니다.그리드를 기반으로 사용자 컨트롤을 설계하는 대신 스타일 선언을 사용하여 그리드에 포함된 컨트롤을 대상으로 지정할 수 있습니다.번거롭고 노동 집약적인 모든 요소에 대해 정의할 필요 없이 모든 요소에 패딩/마진을 추가합니다.예를 들어 그리드에 TextBlock만 포함된 경우 다음 작업을 수행할 수 있습니다.
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Margin" Value="10"/>
</Style>
이것은 "셀 패딩"과 같은 것입니다.
이 솔루션이 게시된 것을 아직 보지 못한 것이 놀랍습니다.
웹에서 제공되는 부트스트랩과 같은 프레임워크는 행/열을 뒤로 당기기 위해 마이너스 마진을 사용합니다.
약간 장황할 수도 있습니다(그렇게 나쁘지는 않지만). 효과가 있고 요소의 간격과 크기가 균일합니다.
아래의 예에서 나는 다음을 사용합니다.StackPanel
3개의 버튼이 여백을 사용하여 균일한 간격으로 배치되는 방법을 보여줍니다.다른 요소를 사용할 수도 있습니다. 내부 x:유형을 단추에서 사용자의 요소로 변경하기만 하면 됩니다.
아이디어는 간단합니다. 외부의 그리드를 사용하여 요소의 여백을 경계 밖으로 반으로 끌어내고(음의 여백 사용), 내부 그리드를 사용하여 원하는 양으로 요소의 공간을 고르게 배치합니다.
업데이트: 작동하지 않는다는 사용자의 의견이 있습니다. 여기 https://youtu.be/rPx2OdtSOYI 을 보여주는 빠른 비디오가 있습니다.
<StackPanel>
<Grid>
<Grid.Resources>
<Style TargetType="{x:Type Grid}">
<Setter Property="Margin" Value="-5 0"/>
</Style>
</Grid.Resources>
<Grid>
<Grid.Resources>
<Style TargetType="{x:Type Button}">
<Setter Property="Margin" Value="10 0"/>
</Style>
</Grid.Resources>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Button Grid.Column="0" Content="Btn 1" />
<Button Grid.Column="1" Content="Btn 2" />
<Button Grid.Column="2" Content="Btn 3" />
</Grid>
</Grid>
<TextBlock FontWeight="Bold" Margin="0 10">
Test
</TextBlock>
</StackPanel>
편집:
컨트롤에 여유를 주기 위해 컨트롤을 테두리로 묶을 수 있습니다.
<!--...-->
<Border Padding="10">
<AnyControl>
<!--...-->
당신은 당신 자신의 것을 쓸 수 있습니다.GridWithMargin
클스래, 상됨에서 Grid
그리고 그것을 무시합니다.ArrangeOverride
을
저는 제 그리드 중 하나로 지금 당장 그것을 했습니다.
- 먼저 그리드 내의 모든 요소에 동일한 여백을 적용합니다.스타일이나 원하는 것을 사용하여 수동으로 수행할 수 있습니다.수평 간격이 6px이고 수직 간격이 2px라고 가정합니다.그런 다음 그리드의 모든 하위 항목에 "3px 1px"의 여백을 추가합니다.
- 그런 다음 그리드 주변에 생성된 여백을 제거합니다(그리드 내부의 컨트롤 경계를 그리드의 동일한 위치에 정렬하려는 경우).그리드에 "-3px -1px"의 여백을 설정합니다.이렇게 하면 그리드 외부의 다른 컨트롤이 그리드 내부의 가장 바깥쪽 컨트롤과 정렬됩니다.
최근에 소프트웨어를 개발하던 중 이 문제가 발생했는데 왜 그러냐고 묻게 되었습니다.왜 이런 짓을...답은 바로 내 앞에 있었습니다.데이터 행은 개체이므로 개체 방향을 유지하는 경우 특정 행에 대한 설계를 분리해야 합니다(나중에 행 표시를 다시 사용해야 하는 경우).그래서 저는 대부분의 데이터 디스플레이에 데이터 바인딩 스택 패널과 사용자 지정 컨트롤을 사용하기 시작했습니다.목록은 가끔 나타나지만 대부분의 그리드는 기본 페이지 구성(헤더, 메뉴 영역, 내용 영역, 기타 영역)에만 사용되었습니다.사용자 지정 개체는 스택 패널 또는 그리드 내의 각 행에 대한 간격 요구 사항을 쉽게 관리할 수 있습니다(단일 그리드 셀에 전체 행 개체가 포함될 수 있음).이는 방향의 변화, 팽창/붕괴 등에 적절히 대응할 수 있는 추가적인 이점도 있습니다.
<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를 상속합니다. 이 접근 방식의 개인적인 장점입니다.
최근에 두 개의 열 그리드에서 비슷한 문제가 발생했습니다. 오른쪽 열의 요소에 대해서만 마진이 필요했습니다.두 열의 모든 요소가 TextBlock 유형입니다.
<Grid.Resources>
<Style TargetType="{x:Type TextBlock}" BasedOn="{StaticResource OurLabelStyle}">
<Style.Triggers>
<Trigger Property="Grid.Column" Value="1">
<Setter Property="Margin" Value="20,0" />
</Trigger>
</Style.Triggers>
</Style>
</Grid.Resources>
원하는 패딩/마진으로 사용할 고정 너비 행과 열을 추가할 수 있습니다.
또한 컨테이너 크기에 의해 제한되며 그리드가 포함 요소 또는 지정된 너비와 높이만큼 커집니다.너비나 높이가 설정되지 않은 열과 행을 사용할 수 있습니다.이렇게 하면 기본적으로 그리드 내의 전체 공간을 균등하게 분할할 수 있습니다.그러면 그리드 내에서 요소의 중심을 수직 및 수평으로 맞추는 것이 됩니다.
또 다른 방법은 모든 그리드 요소를 고정된 크기와 여유가 고정된 단일 행 및 열 그리드로 래핑하는 것입니다.그리드에 실제 요소가 포함된 고정 너비/높이 상자가 포함되어 있는지 확인합니다.
inuwp(Windows10FallCreators업데이트 버전 이상)
<Grid RowSpacing="3" ColumnSpacing="3">
그리드에 여백이나 패딩을 추가할 수는 없지만 프레임(또는 유사한 컨테이너)과 같은 것을 사용하여 적용할 수 있습니다.
이렇게 하면(버튼 클릭 시 컨트롤을 표시하거나 숨길 경우) 상호 작용할 수 있는 모든 컨트롤에 여백을 추가할 필요가 없습니다.
컨트롤 그룹을 장치로 분리한 다음 해당 장치에 스타일을 적용하는 것으로 간주합니다.
앞에서 설명한 대로 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>
때로는 간단한 방법이 가장 좋습니다.그냥 줄에 공백을 채우세요.텍스트 상자 등 몇 개만 있으면 가장 간단한 방법입니다.
크기가 고정된 빈 열/행을 삽입할 수도 있습니다.매우 간단하고 쉽게 변경할 수 있습니다.
언급URL : https://stackoverflow.com/questions/1319974/wpf-grid-with-column-row-margin-padding
'sourcecode' 카테고리의 다른 글
python-m 플래그의 의미 (0) | 2023.05.28 |
---|---|
프로세스 권한을 프로그래밍 방식으로 승격하시겠습니까? (0) | 2023.05.28 |
iPhone/iPad의 UI 레이블에서 굵고 기울임꼴로 설정하려면 어떻게 해야 합니까? (0) | 2023.05.23 |
도움말()이 메서드 서명을 나열하는 경우 슬래시는 무엇을 의미합니까? (0) | 2023.05.23 |
C#에서 if/else를 사용하는 것과 switch-case를 사용하는 것 사이에 큰 차이가 있습니까? (0) | 2023.05.23 |