带有SharedSizeGroup列的网格的行为非常奇怪(*NOT*无限循环)
本文关键字:NOT 无限循环 非常 SharedSizeGroup 网格 带有 | 更新日期: 2023-09-27 18:20:12
如果运行上方ItemsControl下方的示例窗口,则会更新布局几秒钟,直到最终所有列都具有正确的宽度(correct=与下方ItemsControl内的列相同)。
您可以更改窗口的宽度,并水平和垂直滚动ScrollViewer周围较低的ItemsControls,但一旦更改窗口的高度,布局就会翻转几秒钟。
注意:在网格无限更新大小的其他问题中,没有大小模糊性。
是我做错了什么吗?如果是,我该怎么解决还是应该将此问题发布到Microsoft Connect?
代码背后:
namespace DynamicGridColumnBinding
{
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
public partial class MainWindow
{
private static readonly CultureInfo[] cultureInfos =
CultureInfo.GetCultures(CultureTypes.NeutralCultures).Take(15).ToArray();
public MainWindow()
{
this.InitializeComponent();
}
public static IEnumerable<CultureInfo> AllCultures
{
get { return cultureInfos; }
}
private void GridInitialized(object sender, EventArgs e)
{
var grid = (Grid)sender;
for ( int i = 0; i < cultureInfos.Length; i++ )
grid.ColumnDefinitions.Add(new ColumnDefinition
{
Width = GridLength.Auto,
SharedSizeGroup = "g" + i,
});
}
private void ScrollViewerScrollChanged(object sender, ScrollChangedEventArgs e)
{
if ( e.HorizontalChange != 0 )
this.legendScroller.ScrollToHorizontalOffset(e.HorizontalOffset);
}
}
}
Xaml:
<FrameworkElement.Resources>
<ItemsPanelTemplate x:Key="panelTemplate">
<Grid Initialized="GridInitialized" />
</ItemsPanelTemplate>
<Style TargetType="ContentPresenter" x:Key="containerStyle">
<Setter Property="Tag" Value="{Binding RelativeSource={RelativeSource Self}, Path=(ItemsControl.AlternationIndex)}" />
<Setter Property="Grid.Column" Value="{Binding RelativeSource={RelativeSource Self}, Path=(ItemsControl.AlternationIndex)}" />
</Style>
<Style TargetType="TextBlock" x:Key="textStyle">
<Setter Property="Padding" Value="5" />
<Setter Property="Background" Value="Lime" />
<Setter Property="HorizontalAlignment" Value="Center" />
<Setter Property="VerticalAlignment" Value="Center" />
</Style>
</FrameworkElement.Resources>
<DockPanel Grid.IsSharedSizeScope="True" DataContext="{Binding Source={x:Static local:MainWindow.AllCultures}}">
<ScrollViewer DockPanel.Dock="Top" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Disabled"
x:Name="legendScroller">
<ItemsControl ItemsSource="{Binding}" AlternationCount="{x:Static System:Int32.MaxValue}" Margin="0 0 500 0"
ItemsPanel="{StaticResource panelTemplate}" ItemContainerStyle="{StaticResource containerStyle}">
<ItemsControl.ItemTemplate>
<DataTemplate DataType="{x:Type glob:CultureInfo}">
<GroupBox Header="{Binding Name}" HeaderStringFormat="[ {0} ]">
<TextBlock Style="{StaticResource textStyle}"
Text="{Binding Tag, RelativeSource={RelativeSource AncestorType=ContentPresenter, AncestorLevel=2}}" />
</GroupBox>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
<TextBlock Foreground="Red" DockPanel.Dock="Top" Margin="0 10" FontSize="20" Text="some random arbitrary content in between" />
<ScrollViewer HorizontalScrollBarVisibility="Visible" VerticalScrollBarVisibility="Auto" ScrollChanged="ScrollViewerScrollChanged">
<ItemsControl ItemsSource="{Binding}" AlternationCount="{x:Static System:Int32.MaxValue}"
ItemsPanel="{StaticResource panelTemplate}" ItemContainerStyle="{StaticResource containerStyle}">
<ItemsControl.ItemTemplate>
<DataTemplate DataType="{x:Type glob:CultureInfo}">
<Border Background="DodgerBlue" Padding="5" Margin="1">
<GroupBox Header="{Binding DisplayName}">
<TextBlock Style="{StaticResource textStyle}" Padding="5 100"
Text="{Binding Tag, RelativeSource={RelativeSource AncestorType=ContentPresenter, AncestorLevel=2}}" />
</GroupBox>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</DockPanel>
BTW:如果你强制上层ItemsControl的项目进行大小给定(通过将MinWidth="200"
添加到GroupBox),那么下层ItemsControl就会表现得很傻。
BTW2:从大约8个共享大小的列开始(在示例中有15个,由.Take(15)
控制),您可以看到重新排列的出现,并且添加的每一列的时间都会翻倍——因此20个列在几分钟内几乎不会结束。
BTW3:在3个月内没有收到任何评论是非常令人沮丧的
有趣的是,我+1在三个月前提出了这个问题,但没有回答。你没有收到回复的原因可能是因为这很难!
我现在仍然没有太多要说的,除了WPF布局是在两个过程中执行的——测量和排列——随后元素的大小可能会触发其他元素的布局等等
为了正确调整列的大小,WPF正在做这样的事情:
- 测量第1列内容
- 排列第1列内容
- 测量第2列内容
- 请稍等,第2列大于预期
- 对所有第1列内容触发度量值
- 排列第1列内容
- 测量第2列内容
etc
为我过于简单的观点道歉。您有多少列(因此共享大小组的数量)?另一个问题。您正在运行什么操作系统和.NET Framework?我听说在WindowsXP上的WPF中可以拥有的SharedSizeGroups的数量有限制。不确定它是否在以后的操作系统中修复。
作为一种变通方法,你能自己实现这种行为吗?这意味着你能制作自己的附加属性来测量网格中的每个元素(所有列、所有行),然后设置每列的大小一次吗?与逐列基础相反。
问候,
我也遇到了类似的问题。我的确切情况以及我是如何解决的。
我构建了一个"网格",当其他内容滚动时,最上面的一行和左边的一列保持不变(就像冻结的Excel单元格)。内容的大小各不相同,并在运行时确定。也很难预测其规模
为了构建它,我总共有4个网格-1个用于布局的外部网格和3个内部网格-一个用于顶行元素,一个用于左列元素,1个用于实际内容。内容网格的行通过共享大小组与左列的行同步,同样与内容的列和顶行列同步。
为了解决这个问题,我首先在代码后面填充了实际网格的数据。然后我在外部网格对象上调用了Measure and Arrange来强制渲染它。https://stackoverflow.com/a/4890217/2352625
通过强制渲染,我得到了每个单元格的实际大小,然后我用它来创建标题的行和列定义(而不是将它们设置为"自动大小")。它仍然不完美——当我显示一个大网格时——但偏移很小(几个像素),而不是像以前那样到处跳跃。