首先,我有一个ItemsControl
,旨在显示几组内容;在每个组中,还有另一个ItemsControl
,其目的是在内部显示Button
个。{/ p>
我的.xaml:
<Window x:Class="CX11TestSolution.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="768"
Width="1024">
<ItemsControl ItemsSource="{Binding HahaList}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition />
</Grid.RowDefinitions>
<Label Content="{Binding Name}" />
<ItemsControl Grid.Row="1"
ItemsSource="{Binding ItemList}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Columns="5" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Content="{Binding Name}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Columns="1" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
我的.xaml.cs:
public partial class MainWindow : Window
{
public IEnumerable<SomeClass> HahaList { get; }
public MainWindow()
{
InitializeComponent();
DataContext = this;
HahaList = new List<SomeClass>()
{
new SomeClass("Group 1", new List<SomeClass>() {
new SomeClass("11"),
new SomeClass("12"),
new SomeClass("13"),
new SomeClass("14"),
new SomeClass("15"),
new SomeClass("16"),
}),
new SomeClass("Group 2", new List<SomeClass>() {
new SomeClass("21"),
new SomeClass("22"),
new SomeClass("23"),
new SomeClass("24"),
}),
new SomeClass("Group 3", new List<SomeClass>() {
new SomeClass("31"),
new SomeClass("32"),
new SomeClass("33"),
}),
new SomeClass("Group 4", new List<SomeClass>() {
new SomeClass("41"),
new SomeClass("42"),
}),
new SomeClass("Group 5", new List<SomeClass>() {
new SomeClass("52"),
}),
};
}
}
public class SomeClass
{
public string Name { get; }
public IEnumerable<SomeClass> ItemList { get; }
public SomeClass(string name, IEnumerable<SomeClass> list)
{
Name = name;
ItemList = list;
}
public SomeClass(string name)
{
Name = name;
}
}
所以我的问题是,我如何平均拉伸按钮的高度,以便填充整个区域?
我实际上已经尝试将父ItemsPanel
的{{1}}设置为ItemsControl
为UniformGrid
的{{1}},当按钮数量确实有效时在每组中不超过5.当它超过5时,第六个按钮将跳到下一行,从而缩小第一行以使每组具有相等的高度。
提前谢谢。
答案 0 :(得分:1)
我会用网格手动完成此操作。您知道最多有5列,因此很容易计算出包含所有内容的网格所需的列数和行数。使用附加行为以便您可以在运行时动态设置网格的行和列,您还需要一个标志来指定每行是“自动”(标题)还是“1 *”(等间距)。最后,为Grid列和行号添加字段到SomeClass并绑定到XAML中的字段。
在纯XAML中或者使用自定义布局类可能有一种方法可以做到这一点,但我上面描述的方法只需要10分钟左右来编码,并且很容易测试和调试,所以你可能会节省自己从长远来看,很多人都很头疼。
更新:
我刚刚实现了这样做的方法,它要求你将它添加到主视图模型中:
public int RowCount { get; set; }
public int ColumnCount {get; set; }
public string StarCount { get; set; }
public string StarRows { get; set; }
public string StarColumns { get; set; }
public List<Tuple<SomeClass, bool>> AllItems { get; set; } // second parameter indicates whether it's a header
private void UpdateGridLayout()
{
this.AllItems = new List<Tuple<SomeClass, bool>>();
this.ColumnCount = 5;
this.RowCount = HahaList.Sum(x => 1 + (x.ItemList.Count() + this.ColumnCount - 1) / this.ColumnCount);
int row = 0;
this.StarColumns = String.Join(",", Enumerable.Range(0, this.ColumnCount).Select(i => i.ToString())); // all columns
this.StarRows = null;
foreach (var section in this.HahaList)
{
this.AllItems.Add(new Tuple<SomeClass, bool>(section, true));
section.Row = row;
section.Column = 0;
section.ColumnSpan = this.ColumnCount;
row++;
if (StarRows != null)
StarRows += ",";
StarRows += row.ToString();
int column = 0;
foreach (var item in section.ItemList)
{
this.AllItems.Add(new Tuple<SomeClass, bool>(item, false));
item.Row = row;
item.Column = column++;
item.ColumnSpan = 1;
if (column >= this.ColumnCount)
{
column = 0;
row++;
if (StarRows != null)
StarRows += ",";
StarRows += row.ToString();
}
}
row++;
}
return;
}
在设置HahaList后需要调用UpdateGridLayout,如果你想要支持动态更改,那么显然你必须完成所有操作并添加INPC。这段代码的一个值得注意的区别是添加了“AllItems”属性,该属性包含头部和叶子节点以及一个标志,指示每个类型的类型(我自己会使用不同的类,因此您不必这样做)。
SomeClass还需要一些额外的属性:
public int Row { get; set; }
public int Column { get; set; }
public int ColumnSpan { get; set; }
这是XAML:
<ItemsControl ItemsSource="{Binding AllItems}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Grid local:GridHelpers.RowCount="{Binding RowCount}"
local:GridHelpers.ColumnCount="{Binding ColumnCount}"
local:GridHelpers.StarRows="{Binding StarRows}"
local:GridHelpers.StarColumns="{Binding StarColumns}"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style>
<Setter Property="Grid.Row" Value="{Binding Item1.Row}" />
<Setter Property="Grid.Column" Value="{Binding Item1.Column}" />
<Setter Property="Grid.ColumnSpan" Value="{Binding Item1.ColumnSpan}" />
</Style>
</ItemsControl.ItemContainerStyle>
<ItemsControl.ItemTemplate>
<DataTemplate>
<ContentControl>
<ContentControl.Style>
<Style TargetType="ContentControl">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Label Content="{Binding Item1.Name}" />
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding Item2}" Value="false">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Button Content="{Binding Item1.Name}" />
</ControlTemplate>
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</ContentControl.Style>
</ContentControl>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
XAML使用名为GridHelpers的类来帮助创建动态行和列,您可以从Rachael Lim's Blog获取源代码。
结果:
答案 1 :(得分:0)
这是可以使用Viewbox
的地方,但它带有副作用。
更改按钮上的MinWidth以获得你喜欢的Label to Button比率,因为当窗口缩小时设计会受到影响,但是当尺寸增加时,设计会正常。
<强>代码强>
<Viewbox Stretch="Fill">
<ItemsControl ItemsSource="{Binding HahaList}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Label Content="{Binding Name}"/>
<ItemsControl Grid.Row="1"
ItemsSource="{Binding ItemList}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Columns="5"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Content="{Binding Name}" MinWidth="75"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</Viewbox>