template .net wpf xaml itemscontrol

.net - template - listbox wpf



Controles de estiramiento para llenar ItemsControl (3)

Pude basarme en la respuesta de Nir para cumplir con mi criterio opcional, que permite el estiramiento administrado por WPF con múltiples filas.

Primero debe poder alterar las propiedades de la plantilla UniformGrid . Para hacer eso, necesitas almacenar una referencia a él. Existen múltiples métodos para lograr esto . Elegí manejar el evento Loaded para UniformGrid y almacenar una referencia en ese momento.

<ItemsControl ItemsSource="{Binding}"> <ItemsControl.ItemsPanel> <ItemsPanelTemplate> <UniformGrid Rows="1" Loaded="UniformGrid_Loaded" /> </ItemsPanelTemplate> </ItemsControl.ItemsPanel> </ItemsControl>

Y en el código detrás:

UniformGrid uniformgridButtons; private void UniformGrid_Loaded(object sender, RoutedEventArgs e) { uniformgridButtons = sender as UniformGrid; }

Luego, maneje el evento SizeChanged y ajuste el parámetro de filas de acuerdo con los criterios que desee.

private void Window_SizeChanged(object sender, SizeChangedEventArgs e) { if ((uniformgridButtons != null) && (this.Width > 0)) { // Set row count according to your requirements uniformgridButtons.Rows = (int)(1 + ((this.MinWidth * iButtonCount) / this.Width)); } }

Esto permite que WPF administre el estiramiento como en la respuesta de Nir, pero le permite ajustar explícitamente el número de filas. El código anterior da este resultado:

(Muestra animada here )

Actualización 28/08/2009:

Estaba ajustando mi aplicación de aprendizaje para que ItemsControl estuviera en un DataTemplate en un ResourceDictionary separado. Sin embargo, eventos como Loaded no se pueden manejar en un archivo ResourceDictionary XAML externo porque no tiene código subyacente (generalmente). Por lo tanto, necesitaba UniformGrid la memoria caché la referencia a UniformGrid usando una técnica diferente.

En su lugar , FindItemsPanel método FindItemsPanel Alan Haigh (10ª respuesta) . Primero, reemplacé el ItemsControl por:

<ContentPresenter x:Name="contentpresenterButtons" Content="{Binding obscolButtons}" />

Luego, en mi ResourceDictionary , puse el ItemsControl en DataTemplate :

<DataTemplate DataType="{x:Type local:Buttons}"> <ItemsControl ... </DataTemplate>

Finalmente, UniformGrid la referencia al UniformGrid plantilla así:

private void Window_Loaded(object sender, RoutedEventArgs e) { uniformgridButtons = FindItemsPanel<UniformGrid>(contentpresenterButtons); // Also call the code in Window_SizeChanged which I put in another method }

Esto funciona igual que mi solución anterior pero sin requerir un controlador de eventos en ResourceDictionary .

Estoy intentando escribir un proyecto de aprendizaje de WPF simple que crea un conjunto de botones dentro de una ventana principal redimensionable. Debe haber un Button por entrada en una colección, y el contenido de esa colección puede variar durante el tiempo de ejecución. Quiero que los botones llenen toda la ventana (por ejemplo, 1 botón @ 100% de ancho, 2 botones @ 50% de ancho, 3 botones a 33% de ancho, etc., todos al 100% de altura). Una versión simplificada de lo que he escrito hasta ahora es:

<ItemsControl x:Name="itemscontrolButtons" ItemsSource="{Binding}"> <ItemsControl.ItemTemplate> <DataTemplate> <Button Tag="{Binding}"> <TextBlock Text="{Binding}" /> </Button> </DataTemplate> </ItemsControl.ItemTemplate> <ItemsControl.ItemsPanel> <ItemsPanelTemplate> <StackPanel Orientation="Horizontal" /> </ItemsPanelTemplate> </ItemsControl.ItemsPanel> </ItemsControl> ... List<string> listButtonTexts = new List<string>() { "Button1", "Button2" }; ... itemscontrolButtons.DataContext = listButtonTexts;

Esto resulta en esto:

No he podido hacer que los botones se estiren para que se ajusten al ancho y mis intentos de usar una Grid lugar de StackPanel fueron infructuosos.

Luego, como una mejora opcional, agradecería sugerencias sobre cómo ajustarlo de manera que si hay tantos botones que no pueden caber correctamente en una línea o si son más angostos que un umbral, se envolverá en una nueva línea (reduciendo a la mitad la alturas de los botones si van de 1 a 2 filas).

Me gustaría enfatizar que me gustaría saber cómo hacer esto de la manera WPF . Me doy cuenta de que puedo consumir mensajes de cambio de tamaño de ventana y cambiar el tamaño de los controles de forma explícita, y así es como lo hubiera hecho con MFC o WinForms, pero por lo que he leído, no es así como deberían hacerse con WPF.


Reemplace el panel del control del artículo con un UniformGrid, esto ajustará el tamaño de todos los niños para que todo encaje exactamente:

<ItemsControl> <ItemsControl.ItemsPanel> <ItemsPanelTemplate> <UniformGrid Rows="1"/> </ItemsPanelTemplate> </ItemsControl.ItemsPanel> </ItemsControl>


<!-- width must be explicitly set for this example --> <StackPanel Name="MyStack" Orientation="Horizontal" Width="250" Load="Window_Loaded"> <Button/> <Button/> <Button/> </StackPanel>

public void Window_Loaded(object sender, RoutedEventArgs e) { UIElementCollection elements = MyStack.Children; int count = elements.Count; foreach (UIElement element in elements) { if (element is Button) ((Button)element).Width = MyStack.Width / count; } }