Se si esegue la finestra di esempio sotto la parte superiore di ItemsControl si aggiornerà il layout per diversi secondi finché tutte le colonne avranno la larghezza corretta (corretta = identica alle colonne all'interno del lower ItemsControl).Le griglie con le colonne SharedSizeGroup si comportano in modo molto strano (* NON * ciclo infinito)
È possibile modificare la larghezza della finestra e scorrere gli oggetti in basso che circondano ScrollViewer sia orizzontalmente che verticalmente, ma non appena si modifica l'altezza della finestra, il layout si inverte per alcuni secondi.
Nota: non vi è alcuna ambiguità di ridimensionamento come in altre domande in cui la griglia aggiorna infinitamente le dimensioni.
Sto facendo qualcosa di sbagliato? E se sì, come potrei risolvere questo? - o dovrei inviare questo problema a Microsoft-Connect?
codice dietro:
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: Se si forza le voci del ItemsControl superiore di essere formato dare (con l'aggiunta di MinWidth="200"
a GroupBox) quindi il lower ItemsControl agirà invece in modo sciocco.
BTW2: a partire da ca. 8 colonne di dimensioni condivise (nel campione ci sono 15, controllate da .Take(15)
) si vede apparire il riarrangiamento e raddoppia nel tempo per ogni colonna aggiunta, quindi 20 colonne non si chiudono per minuti.
BTW3: Ricevere un singolo commento durante 3 mesi è molto frustrante.
La quantità di colonne varia in fase di esecuzione. Sto usando .NET su W7. Non riesco a misurare tutte le colonne e tutte le righe perché uno dei 2 assi deve utilizzare un VirtualizedStackpanel. Forse dovrei scrivere il mio pannello usando la sua semantica SharedSize. Attualmente sto solo disabilitando l'assegnazione dei nomi SharedSizeGroup se ci sono più di 7 colonne. – springy76
Sì, ci siamo appena imbattuti in questo. Abbiamo avuto 10 righe di gruppo condivise e ci sono voluti alcuni secondi prima che la dimensione si stabilizzasse dopo aver aggiunto un nuovo set di righe. Nel nostro caso sembrava che la maggior parte delle righe avessero effettivamente una dimensione fissa che poteva essere codificata nell'XAML. Una volta che il numero di gruppi condivisi è stato ridotto a 2 (questo era il numero che in realtà doveva essere dimensionato dinamicamente) il problema è andato via. Quindi sembra che tu abbia bisogno di usare questa proprietà con parsimonia. – briantyler
Quello che non capisco è: la misura a 2 passaggi e il processo di arrangiamento normalmente avvengono senza cicli di verniciatura in mezzo. Se la tua finestra contiene troppi controlli, l'aggiornamento dell'interfaccia utente può essere ritardato per diversi secondi e l'intera app "sembra" essere congelata nel frattempo (il thread principale è davvero). – springy76