带有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个月内没有收到任何评论是非常令人沮丧的

带有SharedSizeGroup列的网格的行为非常奇怪(*NOT*无限循环)

有趣的是,我+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

通过强制渲染,我得到了每个单元格的实际大小,然后我用它来创建标题的行和列定义(而不是将它们设置为"自动大小")。它仍然不完美——当我显示一个大网格时——但偏移很小(几个像素),而不是像以前那样到处跳跃。