Si ejecuta la ventana de muestra a continuación, ItemsControl actualizará el diseño durante varios segundos hasta que finalmente todas las columnas tengan el ancho correcto (correcto = idéntico a las columnas dentro de ItemsControl inferior).Cuadrícula con columnas SharedSizeGroup está actuando muy raro (* NO * bucle infinito)
Puede cambiar el ancho de la ventana y desplazarse por los controles de elementos inferiores que rodean ScrollViewer, tanto horizontal como verticalmente, pero tan pronto como cambie la altura de la ventana, el diseño se invertirá durante varios segundos.
Nota: No existe una ambigüedad de tamaño como en otras preguntas donde la cuadrícula actualiza infinitamente los tamaños.
¿Debo hacer algo mal? Si es así, ¿cómo podría solucionarlo? ¿O debería publicar este problema en Microsoft-Connect?
Código atrás:
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>
Por cierto: Si se obliga a los elementos de ItemsControl superior a estar dando tamaño (mediante la adición de MinWidth="200"
a GroupBox) entonces el ItemsControl inferior en cambio actuará tontamente.
BTW2: Comenzando con aprox. 8 columnas de tamaño compartido (en el ejemplo hay 15, controladas por .Take(15)
) se ve la reordenación para aparecer, y se duplica en el tiempo por cada columna que se agrega, por lo que 20 columnas casi no terminan durante unos minutos.
BTW3: No recibir un solo comentario durante 3 meses es muy frustrante.
La cantidad de columnas varía en el tiempo de ejecución. Estoy usando .NET en W7. No puedo medir todas las columnas y todas las filas porque uno de los 2 ejes tiene que usar un panel de paneles virtualizado. Tal vez debería escribir mi propio Panel usando su propia semántica SharedSize. Actualmente estoy desactivando la asignación de SharedSizeGroup-names si hay más de 7 columnas. – springy76
Sí, acabamos de encontrarnos con esto. Teníamos 10 filas de grupos compartidas y el proceso tardaba unos segundos en estabilizarse después de agregar un nuevo conjunto de filas. En nuestro caso, parecía que la mayoría de las filas eran en realidad de un tamaño fijo que podía codificarse en el XAML. Una vez que la cantidad de grupos compartidos se redujo a 2 (este era el número que realmente se necesitaba para tener un tamaño dinámico), el problema desapareció. Entonces parece que necesita usar esta propiedad con moderación. – briantyler
Lo que no entiendo es: El proceso de medición y organización de 2 pasos normalmente ocurre sin ningún ciclo de pintura entre ellos. Si su ventana contiene demasiados controles, la actualización de la interfaz de usuario se puede retrasar durante varios segundos y toda la aplicación "parece" estar congelada mientras tanto (el hilo principal realmente lo es). – springy76