Apakah mudah untuk menentukan margin dan / atau padding untuk baris atau kolom di WPF Grid?
Saya tentu saja dapat menambahkan kolom ekstra untuk mengatur ruang, tetapi ini sepertinya pekerjaan untuk padding / margin (ini akan memberikan XAML yang jauh lebih sederhana). Apakah seseorang berasal dari Grid standar untuk menambahkan fungsi ini?
Jawaban:
Anda dapat menulis
GridWithMargin
kelas Anda sendiri , mewarisi dariGrid
, dan menggantiArrangeOverride
metode untuk menerapkan marginsumber
RowDefinition
danColumnDefinition
bertipeContentElement
, danMargin
benar-benar merupakanFrameworkElement
properti. Jadi untuk pertanyaan Anda, "apakah itu mungkin mudah" , jawabannya pasti tidak. Dan tidak, saya belum melihat panel tata letak yang mendemonstrasikan fungsi semacam ini.Anda dapat menambahkan baris atau kolom tambahan seperti yang Anda sarankan. Tapi Anda juga bisa mengatur margin pada
Grid
elemen itu sendiri, atau apapun yang akan masuk ke dalam aGrid
, jadi itu solusi terbaik Anda untuk saat ini.sumber
Gunakan
Border
kontrol di luar kontrol sel dan tentukan padding untuk itu:<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>
Sumber:
sumber
Anda bisa menggunakan sesuatu seperti ini:
<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>
Atau jika Anda tidak membutuhkan 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>
sumber
Pikir saya akan menambahkan solusi saya sendiri karena belum ada yang menyebutkan ini. Alih-alih mendesain UserControl berdasarkan Grid, Anda dapat menargetkan kontrol yang terdapat dalam grid dengan deklarasi gaya. Menjaga penambahan padding / margin ke semua elemen tanpa harus menentukan masing-masing, yang rumit dan padat karya. Misalnya, jika Grid Anda tidak berisi apa pun selain TextBlocks, Anda dapat melakukan ini:
<Style TargetType="{x:Type TextBlock}"> <Setter Property="Margin" Value="10"/> </Style>
Yang mirip dengan "bantalan sel".
sumber
Margin
properti yang terjadi, bahwa setiapStyle
diResourceDictionary
akan berlaku untuk setiap elemennya diTargetType
mana saja dalam seluruh cakupan elemen pemilik kamus itu. JadiStyle
yang menetes, bukan propertinya.di uwp (versi Windows10FallCreatorsUpdate dan yang lebih baru)
<Grid RowSpacing="3" ColumnSpacing="3">
sumber
Xamarin.Forms
.Saya mengalami masalah ini saat mengembangkan beberapa perangkat lunak baru-baru ini dan terpikir oleh saya untuk bertanya MENGAPA? Mengapa mereka melakukan ini ... jawabannya ada di depan saya. Baris data adalah sebuah objek, jadi jika kita mempertahankan orientasi objek, maka desain untuk baris tertentu harus dipisahkan (misalkan Anda perlu menggunakan kembali tampilan baris nanti di masa mendatang). Jadi saya mulai menggunakan panel tumpukan data dan kontrol kustom untuk sebagian besar tampilan data. Daftar terkadang muncul tetapi sebagian besar kisi telah digunakan hanya untuk organisasi halaman utama (Header, Area Menu, Area Konten, Area Lain). Objek khusus Anda dapat dengan mudah mengelola persyaratan jarak apa pun untuk setiap baris dalam panel tumpukan atau kisi (satu sel kisi dapat berisi seluruh objek baris. Ini juga memiliki manfaat tambahan untuk bereaksi dengan benar terhadap perubahan orientasi,
<Grid> <Grid.RowDefinitions> <RowDefinition /> <RowDefinition /> </Grid.RowDefinitions> <custom:MyRowObject Style="YourStyleHereOrGeneralSetter" Grid.Row="0" /> <custom:MyRowObject Style="YourStyleHere" Grid.Row="1" /> </Grid>
atau
<StackPanel> <custom:MyRowObject Style="YourStyleHere" Grid.Row="0" /> <custom:MyRowObject Style="YourStyleHere" Grid.Row="1" /> </StackPanel>
Kontrol Kustom Anda juga akan mewarisi DataContext jika Anda menggunakan data binding ... manfaat favorit pribadi saya dari pendekatan ini.
sumber
ListView
kontrol WPF dalamGridView
mode, tetapi tanpa ketentuan untuk membuat semua "RowObjects" berbagi lebar kolom yang sama. Pada kenyataannya, itu tidak lagi ada hubungannya dengan Grid.Diedit:
Untuk memberikan margin ke kontrol apa pun Anda bisa membungkus kontrol dengan batas seperti ini
<!--...--> <Border Padding="10"> <AnyControl> <!--...-->
sumber
Saya melakukannya sekarang dengan salah satu grid saya.
sumber
Salah satu kemungkinannya adalah menambahkan baris dan kolom dengan lebar tetap untuk bertindak sebagai bantalan / margin yang Anda cari.
Anda juga dapat mempertimbangkan bahwa Anda dibatasi oleh ukuran penampung Anda, dan bahwa kisi akan menjadi sebesar elemen penampung atau lebar dan tinggi yang ditentukan. Anda cukup menggunakan kolom dan baris tanpa set lebar atau tinggi. Dengan cara itu mereka secara default membagi ruang total dalam grid secara merata. Maka itu hanya akan menjadi mater pemusatan elemen Anda secara vertikal dan horizontal di dalam grid Anda.
Metode lain mungkin untuk membungkus semua elemen grid tetap dengan grid baris & kolom tunggal yang memiliki ukuran dan margin tetap. Bahwa grid Anda berisi kotak lebar / tinggi tetap yang berisi elemen Anda yang sebenarnya.
sumber
Saya mengalami masalah serupa baru-baru ini di kisi dua kolom, saya hanya membutuhkan margin pada elemen di kolom kanan. Semua elemen di kedua kolom berjenis 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>
sumber
Meskipun Anda tidak dapat menambahkan margin atau padding ke Grid, Anda dapat menggunakan sesuatu seperti Frame (atau wadah serupa), yang dapat Anda terapkan.
Dengan begitu (jika Anda menampilkan atau menyembunyikan kontrol pada kata klik tombol), Anda tidak perlu menambahkan margin pada setiap kontrol yang mungkin berinteraksi dengannya.
Anggap saja sebagai mengisolasi grup kontrol ke dalam beberapa unit, lalu menerapkan gaya ke unit tersebut.
sumber
Seperti yang dinyatakan sebelumnya, buat kelas GridWithMargins. Berikut adalah contoh kode kerja saya
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; } }
Pemakaian:
<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>
sumber
Saya terkejut saya belum melihat solusi ini diposting.
Berasal dari web, kerangka kerja seperti bootstrap akan menggunakan margin negatif untuk menarik kembali baris / kolom.
Ini mungkin sedikit bertele-tele (meskipun tidak terlalu buruk), itu berfungsi dan elemen-elemennya diberi jarak dan ukuran yang merata.
Dalam contoh di bawah ini saya menggunakan
StackPanel
root untuk mendemonstrasikan bagaimana 3 tombol ditempatkan secara merata menggunakan margin. Anda bisa menggunakan elemen lain, cukup ubah inner x: Type from button ke elemen Anda.Idenya sederhana, gunakan kisi di luar untuk menarik margin elemen keluar dari batasnya dengan setengah jumlah kisi dalam (menggunakan margin negatif), gunakan kisi dalam untuk meratakan jarak elemen dengan jumlah yang Anda inginkan.
Pembaruan: Beberapa komentar dari pengguna mengatakan itu tidak berfungsi, berikut adalah video singkat yang menunjukkan: 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>
sumber
Terkadang metode sederhana adalah yang terbaik. Cukup isi string Anda dengan spasi. Jika hanya beberapa kotak teks dll, ini adalah metode yang paling sederhana.
Anda juga dapat memasukkan kolom / baris kosong dengan ukuran tetap. Sangat sederhana dan Anda dapat dengan mudah mengubahnya.
sumber