根据SO问题“WPF: arranging collection items in a grid”的答案,我有以下内容:
<ItemsControl Name="itemsControl1" ItemsSource="{Binding MyItems}"> <ItemsControl.ItemsPanel> <ItemsPanelTemplate> <Grid Name="theGrid" ShowGridLines="True" /> </ItemsPanelTemplate> </ItemsControl.ItemsPanel> <ItemsControl.ItemContainerStyle> <Style TargetType="{x:Type FrameworkElement}"> <Setter Property="Grid.Row" Value="{Binding RowIndex}" /> <Setter Property="Grid.Column" Value="{Binding ColumnIndex}" /> </Style> </ItemsControl.ItemContainerStyle> </ItemsControl>
现在,我想在后面的代码中设置theGrid的行数和列数:
theGrid.RowDefinitions.Clear();
theGrid.ColumnDefinitions.Clear();
for (uint i = 0; i < theNumberOfRows; i++)
theGrid.RowDefinitions.Add(new RowDefinition());
for (uint i = 0; i < theNumberOfCols; i++)
theGrid.ColumnDefinitions.Add(new ColumnDefinition());
为此,当然,我需要找到网格。我在问题WPF ways to find controls中使用了CrimsonX的FindChild来首先找到itemsControl1,然后使用它作为父级,找到网格。
Grid FindTheGrid()
{
ItemsControl ic = (ItemsControl)this.FindName("itemsControl1");
Grid theGrid = FindChild<Grid>(ic, "theGrid");
}
从按钮的单击事件处理程序调用时,此方法有效。但是,当从MainWindow的构造函数调用它时失败,因为ic的childrenCount为0。
int childrenCount = VisualTreeHelper.GetChildrenCount(theParent);
那么,如何在向用户显示窗口之前设置网格的行和列集合?
答案 0 :(得分:2)
WPF在后台为ItemsControl的项目(通常是DataTemplate)生成“容器”,它们将不会立即可用。
了解项目何时可用的唯一方法是订阅ItemsControl的ItemContainerGenerator属性上的StatusChanged事件:
itemsControl1.ItemContainerGenerator.StatusChanged += ic_GeneratorStatusChanged;
...然后从事件处理程序中取消订阅,因为你只需要它来触发一次:
void ic_GeneratorStatusChanged(object sender, EventArgs e)
{
if (itemsControl1.ItemContainerGenerator.Status != GeneratorStatus.ContainersGenerated)
return;
itemsControl1.ItemContainerGenerator.StatusChanged -= ic_GeneratorStatusChanged;
// your items are now generated
}
这是一种迂回的做事方式,当然,但这是了解ItemsControl的项目存在于可视化树中的唯一方法。
答案 1 :(得分:1)
我厌倦了为我的网格写出RowDefinitions
和ColumnDefinitions
,因此创建了一些自定义的DependencyProperties,可以让你指定网格定义中的行数/列数。
可以找到依赖项属性的代码here,并按如下方式使用:
<Grid local:GridHelpers.RowCount="{Binding RowCount}"
local:GridHelpers.ColumnCount="{Binding ColumnCount}" />
如果它给你一个关于绑定的错误,那么将DependencyProperty定义中的typeof(Grid)
更改为typeof(GridHelpers)
。我的第一个帮助类版本不允许绑定,我不记得我发布了哪一个。
修改强>
以下是我正在使用的代码,包括在SomeInt
更改时正确更新UI。我在单击按钮
SomeInt
在2和3之间
<强> XAML 强>
<Grid ShowGridLines="True"
local:GridProperties.ColumnCount="{Binding SomeInt}"
local:GridProperties.RowCount="{Binding SomeInt}">
<TextBox Text="Test" Grid.Row="0" Grid.Column="0" />
<TextBox Text="Test" Grid.Row="0" Grid.Column="1" />
<TextBox Text="Test" Grid.Row="0" Grid.Column="2" />
<TextBox Text="Test" Grid.Row="1" Grid.Column="0" />
<TextBox Text="Test" Grid.Row="1" Grid.Column="1" />
<TextBox Text="Test" Grid.Row="1" Grid.Column="2" />
<TextBox Text="Test" Grid.Row="2" Grid.Column="0" />
<TextBox Text="Test" Grid.Row="2" Grid.Column="1" />
<TextBox Text="Test" Grid.Row="2" Grid.Column="2" />
</Grid>
<强>的DependencyProperty 强>
public class GridProperties
{
#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(GridProperties),
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(GridProperties),
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
}
<强>结果强>