Muy bien, la segunda vez es el encanto. Según su captura de pantalla de diseño, puedo inferir de inmediato que lo que necesita es un WrapPanel
, un panel de diseño que permite que los elementos se llenen hasta que llegue a un borde, en cuyo punto los elementos restantes fluyen a la siguiente línea. Pero aún desea utilizar un ItemsControl
para que pueda obtener todos los beneficios de vinculación de datos y generación dinámica. Así que para esto vamos a usar la propiedad ItemsControl.ItemsPanel
, que nos permite especificar el panel en el que se colocarán los elementos. Vamos a empezar con el nuevo código subyacente:
public partial class Window1 : Window
{
public ObservableCollection<Field> Fields { get; set; }
public Window1()
{
InitializeComponent();
Fields = new ObservableCollection<Field>();
Fields.Add(new Field() { Name = "Username", Length = 100, Required = true });
Fields.Add(new Field() { Name = "Password", Length = 80, Required = true });
Fields.Add(new Field() { Name = "City", Length = 100, Required = false });
Fields.Add(new Field() { Name = "State", Length = 40, Required = false });
Fields.Add(new Field() { Name = "Zipcode", Length = 60, Required = false });
FieldsListBox.ItemsSource = Fields;
}
}
public class Field
{
public string Name { get; set; }
public int Length { get; set; }
public bool Required { get; set; }
}
No ha cambiado mucho aquí, pero he editado los campos de ejemplo para adaptarse mejor a su ejemplo. Ahora vamos a ver donde la magia ocurre- el XAML para el Window
:
<Window x:Class="DataBoundFields.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:DataBoundFields"
Title="Window1" Height="200" Width="300">
<Window.Resources>
<local:BoolToVisibilityConverter x:Key="BoolToVisConverter"/>
</Window.Resources>
<Grid>
<ListBox x:Name="FieldsListBox">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Label Content="{Binding Name}" VerticalAlignment="Center"/>
<TextBox Width="{Binding Length}" Margin="5,0,0,0"/>
<Label Content="*" Visibility="{Binding Required, Converter={StaticResource BoolToVisConverter}}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal"
Height="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=ActualHeight}"
Width="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=ActualWidth}"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
</Grid>
En primer lugar, se dará cuenta de que el ItemTemplate
ha cambiado ligeramente. La etiqueta todavía está vinculada a la propiedad de nombre, pero ahora el ancho del cuadro de texto está vinculado a la propiedad de longitud (por lo que puede tener cuadros de texto de longitud variable). Además, he agregado un "*" a cualquier campo que sea necesario, usando un BoolToVisibilityConverter
simplista (que puede encontrar el código para cualquier parte, y no lo publicaré aquí).
Lo principal a notar es el uso de un WrapPanel
en la propiedad ItemsPanel
de nuestro ListBox
. Esto le dice al ListBox
que cualquier elemento que genere debe ser insertado en un diseño envuelto horizontal (esto coincide con su captura de pantalla). Lo que hace que este trabajo sea aún mejor es el enlace de alto y ancho en el panel, lo que dice es "hacer que este panel tenga el mismo tamaño que mi ventana principal". Eso significa que cuando cambio el tamaño del Window
, el WrapPanel
ajusta su tamaño en consecuencia, lo que da como resultado una mejor disposición de los elementos. Las dos capturas de pantalla aquí demuestran esto:
alt text http://img156.imageshack.us/img156/6849/wrappanelfields.png
alt text http://img12.imageshack.us/img12/2426/wrappanelfields2.png
+1, pero creo que el OP quería Longitud y Obligatorio para restringir la entrada. –
Por supuesto, pero no estoy seguro de cómo exactamente quiere usar esas restricciones, así que lo dejé sin ellas. – Charlie
problema es -y probablemente confundí las cosas al usar el nombre de la variable "MyGrid" -Estoy agregando thes a un , no un DataGrid.Esto es un formulario de entrada de datos que tengo que salir en un orden específico. Puede haber 3 etiquetas/combinaciones de cuadros de texto con texboxes que tienen longitudes diferentes en una línea, y 10 en la siguiente línea. Hay diferentes versiones de esta forma, es por eso que los campos se cargan desde la base de datos, y por eso lo llamo dinámico. Por lo tanto, no lo hace encajar bien en un diseño DataGrid y es por eso que estaba tratando de crearlos dinámicamente. Diga que tengo otro campo en el objeto - LastFieldOnLine para designar la nueva línea –
user210757