问题描述
我正在使用 Rachel Lim 的
我想要的:
Xaml:
<ItemsControl ItemsSource="{Binding RowSource}" ><ItemsControl.ItemsPanel><ItemsPanelTemplate><Grid local:GridHelper.RowCount="{Binding RowCount}"/></ItemsPanelTemplate></ItemsControl.ItemsPanel><ItemsControl.ItemContainerStyle><Style TargetType="ContentPresenter"><Setter Property="Grid.Row" Value="{Binding RowNumber}"/></风格></ItemsControl.ItemContainerStyle><ItemsControl.ItemTemplate><数据模板><网格><Grid.RowDefinitions><RowDefinition Height="自动"/><RowDefinition Height="自动"/></Grid.RowDefinitions><网格><Grid.ColumnDefinitions><ColumnDefinition Width="*"/><ColumnDefinition Width="Auto"/></Grid.ColumnDefinitions><数据网格><DataGrid.Columns><DataGridTextColumn Header="Col 1"/><DataGridTextColumn Header="Col 2"/><DataGridTextColumn Header="Col 3"/></DataGrid.Columns></DataGrid><Button Grid.Column="1" Content="Btn"/></网格><GridSplitter Height="5" VerticalAlignment="Bottom" HorizontalAlignment="Stretch" Grid.Row="0" ResizeDirection="Rows" ResizeBehavior="CurrentAndNext"/></网格></数据模板></ItemsControl.ItemTemplate></ItemsControl></网格>
视图模型:
内部类 MyViewModel{公共 ObservableCollection行源{获取;放;}公共 int RowCount { 获取 { 返回 RowSource.Count;} }公共 MyViewModel(){RowSource = new ObservableCollection(){新 RowInfo() { RowNumber = 0 },新 RowInfo() { RowNumber = 1 },新 RowInfo() { RowNumber = 2 }};}}
行信息:
公共类RowInfo{公共 int RowNumber { 获取;内部设置;}}
我认为你的方法完全错误.您不能使用 ItemsControl
,因为 GridSplitter
项目需要在 ItemsPanel
级别而不是在 DataTemplate
- 否则,它将无法工作.
最好在网格本身上使用自定义行为 - 请参阅下面的示例代码:
公共类 GridAutoRowChildBehavior : Behavior{公共静态只读 DependencyProperty ItemTemplateProperty =DependencyProperty.Register("ItemTemplate", typeof(DataTemplate), typeof(GridAutoRowChildBehavior),新的 PropertyMetadata(null, OnGridPropertyChanged));公共静态只读 DependencyProperty ItemsSourceProperty =DependencyProperty.Register("ItemsSource", typeof(object), typeof(GridAutoRowChildBehavior),新的 PropertyMetadata(null, OnGridPropertyChanged));私有静态无效 OnGridPropertyChanged(DependencyObject d,DependencyPropertyChangedEventArgs e){((GridAutoRowChildBehavior) d).ResetGrid();}私有无效重置网格(){var source = ItemsSource 作为 IEnumerable;if (source == null || ItemTemplate == null)返回;AssociatedObject.Children.Clear();AssociatedObject.RowDefinitions.Clear();无功计数 = 0;foreach(源中的 var 项目){var content = 新的 ContentPresenter{内容模板 = 项目模板,内容 = 项目};var splitter = 新的 GridSplitter{高度 = 5,VerticalAlignment = VerticalAlignment.Bottom,HorizontalAlignment = HorizontalAlignment.Stretch};AssociatedObject.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) });Grid.SetRow(content,count);Grid.SetRow(splitter,count);AssociatedObject.Children.Add(content);AssociatedObject.Children.Add(splitter);计数++;}}公共数据模板 ItemTemplate{得到{返回(数据模板)GetValue(ItemTemplateProperty);}set { SetValue(ItemTemplateProperty, value);}}公共对象 ItemsSource{得到 { 返回 GetValue(ItemsSourceProperty);}设置 { SetValue(ItemsSourceProperty, value);}}}
然后在您的 XAML 中像这样编写代码:
<i:Interaction.Behaviors><local:GridAutoRowChildBehavior ItemsSource="{Binding RowsSource}"><local:GridAutoRowChildBehavior.ItemTemplate><数据模板><网格><Grid.ColumnDefinitions><ColumnDefinition Width="*"/><ColumnDefinition Width="Auto"/></Grid.ColumnDefinitions><数据网格><DataGrid.Columns><DataGridTextColumn Header="Col 1"/><DataGridTextColumn Header="Col 2"/><DataGridTextColumn Header="Col 3"/></DataGrid.Columns></DataGrid><Button Grid.Column="1" Content="Btn"/></网格></数据模板></local:GridAutoRowChildBehavior.ItemTemplate></local:GridAutoRowChildBehavior></i:Interaction.Behaviors></网格>
我已经对此进行了测试,它完全符合您的需要.
您唯一需要做的就是将 Nuget 包 Systems.Windows.Interactivity.WPF
添加到您的项目
I'm using Rachel Lim's GridHelper to get dynamic number of rows. What I wanted to achieve is to have each row displayed one below another (done), to be able to resize them (done - using GridSplitter) and to have content resized proportionally to the screen size.
Result:
What I would like to have:
Xaml:
<Grid>
<ItemsControl ItemsSource="{Binding RowSource}" >
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Grid local:GridHelper.RowCount="{Binding RowCount}" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="Grid.Row" Value="{Binding RowNumber}"/>
</Style>
</ItemsControl.ItemContainerStyle>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<DataGrid>
<DataGrid.Columns>
<DataGridTextColumn Header="Col 1" />
<DataGridTextColumn Header="Col 2" />
<DataGridTextColumn Header="Col 3" />
</DataGrid.Columns>
</DataGrid>
<Button Grid.Column="1" Content="Btn" />
</Grid>
<GridSplitter Height="5" VerticalAlignment="Bottom" HorizontalAlignment="Stretch" Grid.Row="0" ResizeDirection="Rows" ResizeBehavior="CurrentAndNext"/>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
ViewModel:
internal class MyViewModel
{
public ObservableCollection<RowInfo> RowSource { get; set; }
public int RowCount { get { return RowSource.Count; } }
public MyViewModel()
{
RowSource = new ObservableCollection<RowInfo>()
{
new RowInfo() { RowNumber = 0 },
new RowInfo() { RowNumber = 1 },
new RowInfo() { RowNumber = 2 }
};
}
}
RowInfo:
public class RowInfo
{
public int RowNumber { get; internal set; }
}
I think your approach is all wrong. You cannot use an ItemsControl
, as the GridSplitter
items need to be at the ItemsPanel
level rather than in the DataTemplate
- otherwise, it won't work.
You are better off using a custom behavior on the Grid Itself - see example code below:
public class GridAutoRowChildBehavior : Behavior<Grid>
{
public static readonly DependencyProperty ItemTemplateProperty =
DependencyProperty.Register("ItemTemplate", typeof(DataTemplate), typeof(GridAutoRowChildBehavior),
new PropertyMetadata(null, OnGridPropertyChanged));
public static readonly DependencyProperty ItemsSourceProperty =
DependencyProperty.Register("ItemsSource", typeof(object), typeof(GridAutoRowChildBehavior),
new PropertyMetadata(null, OnGridPropertyChanged));
private static void OnGridPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((GridAutoRowChildBehavior) d).ResetGrid();
}
private void ResetGrid()
{
var source = ItemsSource as IEnumerable;
if (source == null || ItemTemplate == null)
return;
AssociatedObject.Children.Clear();
AssociatedObject.RowDefinitions.Clear();
var count = 0;
foreach (var item in source)
{
var content = new ContentPresenter
{
ContentTemplate = ItemTemplate,
Content = item
};
var splitter = new GridSplitter
{
Height = 5,
VerticalAlignment = VerticalAlignment.Bottom,
HorizontalAlignment = HorizontalAlignment.Stretch
};
AssociatedObject.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) });
Grid.SetRow(content,count);
Grid.SetRow(splitter,count);
AssociatedObject.Children.Add(content);
AssociatedObject.Children.Add(splitter);
count++;
}
}
public DataTemplate ItemTemplate
{
get { return (DataTemplate) GetValue(ItemTemplateProperty); }
set { SetValue(ItemTemplateProperty, value); }
}
public object ItemsSource
{
get { return GetValue(ItemsSourceProperty); }
set { SetValue(ItemsSourceProperty, value); }
}
}
Then in your XAML you code it up like this:
<Grid>
<i:Interaction.Behaviors>
<local:GridAutoRowChildBehavior ItemsSource="{Binding RowsSource}">
<local:GridAutoRowChildBehavior.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<DataGrid>
<DataGrid.Columns>
<DataGridTextColumn Header="Col 1" />
<DataGridTextColumn Header="Col 2" />
<DataGridTextColumn Header="Col 3" />
</DataGrid.Columns>
</DataGrid>
<Button Grid.Column="1" Content="Btn" />
</Grid>
</DataTemplate>
</local:GridAutoRowChildBehavior.ItemTemplate>
</local:GridAutoRowChildBehavior>
</i:Interaction.Behaviors>
</Grid>
I have tested this and it works exactly as you need.
The only additional thing you need to do is add the Nuget package Systems.Windows.Interactivity.WPF
to your project
这篇关于ItemsControl - 网格子元素自动调整大小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!