我想知道如何设置网格样式,以便我不需要指定
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto" SharedSizeGroup="SG1"/>
<ColumnDefinition Width="auto" SharedSizeGroup="SG2"/>
</Grid.ColumnDefinitions>
每一次?
非常感谢!
ps:我确实首先尝试在Google上搜索。但我找不到任何答案。任何从谷歌找到答案的人都可以告诉我你用什么关键词进行搜索?有时我发现很难确定要搜索的关键字用途。
ps2:我太懒了,每次我都打开chrome并输入内容并搜索。如果找不到任何结果,我得出的结论是什么,来到这里。有没有人会在Google上搜索,然后什么也找不到,然后打开bing.com并搜索?什么都没找到,去雅虎搜索和搜索?.....
答案 0 :(得分:23)
我必须写出RowDefinitions
和ColumnDefinitions
,这总是让我感到内疚,所以有一天我厌倦了它并写了一些attached properties可用于这种事。
现在不是像这样编写我的Grid
定义:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
</Grid>
我可以用
<Grid local:GridHelpers.RowCount="6"
local:GridHelpers.StarRows="5"
local:GridHelpers.ColumnCount="4"
local:GridHelpers.StarColumns="1,3">
</Grid>
它只允许Auto
和*
尺寸,但大部分时间都是我正在使用的尺寸。
它还支持动态大小的网格绑定
<Grid local:GridHelpers.RowCount="{Binding RowCount}"
local:GridHelpers.ColumnCount="{Binding ColumnCount}" />
如果网站出现故障,以下是代码的副本:
public class GridHelpers
{
#region RowCount Property
/// <summary>
/// Adds the specified number of Rows to RowDefinitions.
/// Default Height is Auto
/// </summary>
public static readonly DependencyProperty RowCountProperty =
DependencyProperty.RegisterAttached(
"RowCount", typeof(int), typeof(GridHelpers),
new PropertyMetadata(-1, RowCountChanged));
// Get
public static int GetRowCount(DependencyObject obj)
{
return (int)obj.GetValue(RowCountProperty);
}
// Set
public static void SetRowCount(DependencyObject obj, int value)
{
obj.SetValue(RowCountProperty, value);
}
// Change Event - Adds the Rows
public static void RowCountChanged(
DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
if (!(obj is Grid) || (int)e.NewValue < 0)
return;
Grid grid = (Grid)obj;
grid.RowDefinitions.Clear();
for (int i = 0; i < (int)e.NewValue; i++)
grid.RowDefinitions.Add(
new RowDefinition() { Height = GridLength.Auto });
SetStarRows(grid);
}
#endregion
#region ColumnCount Property
/// <summary>
/// Adds the specified number of Columns to ColumnDefinitions.
/// Default Width is Auto
/// </summary>
public static readonly DependencyProperty ColumnCountProperty =
DependencyProperty.RegisterAttached(
"ColumnCount", typeof(int), typeof(GridHelpers),
new PropertyMetadata(-1, ColumnCountChanged));
// Get
public static int GetColumnCount(DependencyObject obj)
{
return (int)obj.GetValue(ColumnCountProperty);
}
// Set
public static void SetColumnCount(DependencyObject obj, int value)
{
obj.SetValue(ColumnCountProperty, value);
}
// Change Event - Add the Columns
public static void ColumnCountChanged(
DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
if (!(obj is Grid) || (int)e.NewValue < 0)
return;
Grid grid = (Grid)obj;
grid.ColumnDefinitions.Clear();
for (int i = 0; i < (int)e.NewValue; i++)
grid.ColumnDefinitions.Add(
new ColumnDefinition() { Width = GridLength.Auto });
SetStarColumns(grid);
}
#endregion
#region StarRows Property
/// <summary>
/// Makes the specified Row's Height equal to Star.
/// Can set on multiple Rows
/// </summary>
public static readonly DependencyProperty StarRowsProperty =
DependencyProperty.RegisterAttached(
"StarRows", typeof(string), typeof(GridHelpers),
new PropertyMetadata(string.Empty, StarRowsChanged));
// Get
public static string GetStarRows(DependencyObject obj)
{
return (string)obj.GetValue(StarRowsProperty);
}
// Set
public static void SetStarRows(DependencyObject obj, string value)
{
obj.SetValue(StarRowsProperty, value);
}
// Change Event - Makes specified Row's Height equal to Star
public static void StarRowsChanged(
DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
if (!(obj is Grid) || string.IsNullOrEmpty(e.NewValue.ToString()))
return;
SetStarRows((Grid)obj);
}
#endregion
#region StarColumns Property
/// <summary>
/// Makes the specified Column's Width equal to Star.
/// Can set on multiple Columns
/// </summary>
public static readonly DependencyProperty StarColumnsProperty =
DependencyProperty.RegisterAttached(
"StarColumns", typeof(string), typeof(GridHelpers),
new PropertyMetadata(string.Empty, StarColumnsChanged));
// Get
public static string GetStarColumns(DependencyObject obj)
{
return (string)obj.GetValue(StarColumnsProperty);
}
// Set
public static void SetStarColumns(DependencyObject obj, string value)
{
obj.SetValue(StarColumnsProperty, value);
}
// Change Event - Makes specified Column's Width equal to Star
public static void StarColumnsChanged(
DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
if (!(obj is Grid) || string.IsNullOrEmpty(e.NewValue.ToString()))
return;
SetStarColumns((Grid)obj);
}
#endregion
private static void SetStarColumns(Grid grid)
{
string[] starColumns =
GetStarColumns(grid).Split(',');
for (int i = 0; i < grid.ColumnDefinitions.Count; i++)
{
if (starColumns.Contains(i.ToString()))
grid.ColumnDefinitions[i].Width =
new GridLength(1, GridUnitType.Star);
}
}
private static void SetStarRows(Grid grid)
{
string[] starRows =
GetStarRows(grid).Split(',');
for (int i = 0; i < grid.RowDefinitions.Count; i++)
{
if (starRows.Contains(i.ToString()))
grid.RowDefinitions[i].Height =
new GridLength(1, GridUnitType.Star);
}
}
}
答案 1 :(得分:12)
我知道这是一个老问题,但我想提供一个不需要任何帮助类的解决方案。
可以通过使用带有Grid作为ItemsPanelTemplate的ItemsControl来设置ColumnDefinitions。这显示在下面的示例中。
<ItemsControl>
<ItemsControl.Resources>
<Style TargetType="ItemsControl">
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="40" />
</Grid.ColumnDefinitions>
</Grid>
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
</Style>
</ItemsControl.Resources>
<TextBox Text="First column" />
<TextBox Text="second column" Grid.Column="1" />
</ItemsControl>
答案 2 :(得分:7)
使用更改回调创建附加的依赖项属性以同步集合元素:
<Grid>
<Grid.Style>
<Style TargetType="Grid">
<Setter Property="my:GridUtils.ColumnDefinitions">
<Setter.Value>
<my:ColumnDefinitionCollection>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
</my:ColumnDefinitionCollection>
</Setter.Value>
</Setter>
</Style>
</Grid.Style>
<Button Content="Button" />
<Button Content="Button" Grid.Column="1" />
</Grid>
实现(省略RowDefinition支持,因为它基本相同):
public class GridUtils
{
public static readonly DependencyProperty ColumnDefinitionsProperty =
DependencyProperty.RegisterAttached("ColumnDefinitions", typeof (ColumnDefinitionCollection),
typeof (GridUtils),
new PropertyMetadata(default(ColumnDefinitionCollection),
OnColumnDefinitionsChanged));
private static void OnColumnDefinitionsChanged(DependencyObject d, DependencyPropertyChangedEventArgs ev)
{
var grid = (Grid) d;
var oldValue = (ColumnDefinitionCollection) ev.OldValue;
var newValue = (ColumnDefinitionCollection) ev.NewValue;
grid.ColumnDefinitions.Clear();
if (newValue != null)
foreach (var cd in newValue)
grid.ColumnDefinitions.Add(cd);
}
public static void SetColumnDefinitions(Grid element, ColumnDefinitionCollection value)
{
element.SetValue(ColumnDefinitionsProperty, value);
}
public static ColumnDefinitionCollection GetColumnDefinitions(Grid element)
{
return (ColumnDefinitionCollection) element.GetValue(ColumnDefinitionsProperty);
}
}
public class ColumnDefinitionCollection : List<ColumnDefinition> {}
答案 3 :(得分:1)
我认为这是不可能的,因为您无法设置影响所有ColumnDefinition的样式。
Grid不支持ControlTemplate,因此您无法使用合成。
我唯一能想到的黑客就是用这两列创建用户控件并扩展网格。但那太讨厌了。
答案 4 :(得分:1)
这是一种方式:
1)创建一个带有附加属性的集合,如下所示:
public class ColumnDefinitions : Collection<ColumnDefinition>
{
public static readonly DependencyProperty SourceProperty = DependencyProperty.RegisterAttached(
"Source",
typeof(ColumnDefinitions),
typeof(ColumnDefinitions),
new PropertyMetadata(
default(ColumnDefinitions),
OnColumnDefinitionsChanged));
public static void SetSource(Grid element, ColumnDefinitions value)
{
element.SetValue(SourceProperty, value);
}
[AttachedPropertyBrowsableForChildren(IncludeDescendants = false)]
[AttachedPropertyBrowsableForType(typeof(Grid))]
public static ColumnDefinitions GetSource(Grid element)
{
return (ColumnDefinitions)element.GetValue(SourceProperty);
}
private static void OnColumnDefinitionsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var grid = (Grid)d;
grid.ColumnDefinitions.Clear();
var columnDefinitions = (ColumnDefinitions)e.NewValue;
if (columnDefinitions == null)
{
return;
}
foreach (var columnDefinition in columnDefinitions)
{
grid.ColumnDefinitions.Add(columnDefinition);
}
}
}
2)然后你可以将它用作资源和网格样式,如下所示:
请注意,必须使用x:Shared="False"
。如果没有相同的定义将添加到导致WPF抛出的许多网格中。
<UserControl.Resources>
<demo:ColumnDefinitions x:Key="SomeColumnDefinitions" x:Shared="False">
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</demo:ColumnDefinitions>
<Style x:Key="SomeGridStyle" TargetType="{x:Type Grid}">
<Setter Property="demo:ColumnDefinitions.Source" Value="{StaticResource SomeColumnDefinitions}"></Setter>
</Style>
</UserControl.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="5"/>
<RowDefinition />
</Grid.RowDefinitions>
<Grid Style="{StaticResource SomeGridStyle}">
<Rectangle Grid.Row="0"
Grid.Column="0"
Width="120"
Fill="Blue" />
<Rectangle Grid.Row="0"
Grid.Column="1"
Fill="Yellow" />
</Grid>
<Grid Grid.Row="2" Style="{StaticResource SomeGridStyle}">
<Rectangle Grid.Row="0"
Grid.Column="0"
Width="120"
Fill="Blue" />
<Rectangle Grid.Row="0"
Grid.Column="1"
Fill="Yellow" />
</Grid>
</Grid>