두 번째는 매력입니다. 레이아웃 스크린 샷을 기반으로 필요한 항목이 가장자리에 도달 할 때까지 항목을 채울 수있는 레이아웃 패널 인 WrapPanel
을 즉시 추론 할 수 있습니다. 그러면 나머지 항목이 다음 줄로 흘러갑니다. 그러나 여전히 데이터 바인딩 및 동적 생성의 모든 이점을 얻을 수 있도록 ItemsControl
을 사용하려고합니다. 그래서 우리는 아이템을 넣을 패널을 지정할 수있는 ItemsControl.ItemsPanel
속성을 사용할 것입니다. 의 코드 숨김 다시 시작하자 :
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; }
}
많이하지 여기 변경,하지만 난 더 나은 예에 맞게 샘플 필드를 편집했습니다. 이제 마법은 Window
의 XAML을 적 있었 어디를 살펴 보자 :
<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>
먼저, ItemTemplate
이 약간 변경되었음을 알 수 있습니다. 레이블은 여전히 name 속성에 바인딩되어 있지만 이제 텍스트 상자 너비는 length 속성에 바인딩됩니다 (따라서 다양한 길이의 텍스트 상자를 가질 수 있습니다). 또한, 필요한 모든 필드에 "*"를 추가했습니다. 단순한 BoolToVisibilityConverter
을 사용합니다.이 코드는 어디서나 코드를 찾을 수 있으며 여기서는 게시하지 않습니다.
주의해야 할 주요 사항은 의 ItemsPanel
속성에 WrapPanel
을 사용하는 것입니다. 그러면 ListBox
에 생성 된 모든 항목이 가로 포장 된 레이아웃으로 푸시되어야한다는 메시지가 표시됩니다 (스크린 샷과 일치 함). 이 작업을 더욱 효과적으로 만드는 것은 패널의 높이 및 너비 바인딩입니다.이 패널의 크기는 "이 패널을 부모 윈도우와 동일한 크기로 만듭니다."라고 말합니다. 즉, Window
의 크기를 조정하면 WrapPanel
이 크기를 적절하게 조정하므로 항목 레이아웃이 향상됩니다. 두 스크린 샷은 여기 보여줍니다
alt text http://img156.imageshack.us/img156/6849/wrappanelfields.png
alt text http://img12.imageshack.us/img12/2426/wrappanelfields2.png
+1,하지만 OP가 Length를 요구하고 입력을 제한해야한다고 생각합니다. –
물론, 그가 제약 조건을 얼마나 정확히 사용하고 싶은지 잘 모르겠습니다. – Charlie
문제가 있습니다. 변수 이름 "MyGrid"를 사용하여 문제를 혼동 시켰습니다. 이 아니라 DataGrid가 추가되었습니다. 이것은 특정 순서대로 데이터 입력 폼입니다. 레이블이 3 개가있을 수 있습니다./textbox combinesations는 한 줄에 다양한 길이를 가지고 있고 다음 줄에는 10 개가 있습니다.이 양식의 다른 버전이 있는데 왜 데이터베이스에서 필드가로드되고 왜 동적이라고 부르는 것입니까? DataGrid 레이아웃에 잘 맞게 & 이것이 내가 동적으로 만들려고했던 이유입니다. 객체에 다른 필드가 있습니다 - LastFieldOnLine은 새 라인을 지정합니다. – user210757