2010-08-10 4 views
2

나는 완전한 혼란에 빠져있는 많은 XAML을 가지고 있는데, 이는 일반적으로 한 가지 때문입니다. GRID, Grid.ColumnGrid.Row 광란 !!Silverlight/WPF에서 레이블이있는 컨트롤 목록을 만들려면 어떤 옵션이 있습니까?

이제 XAML에서 레이블이있는 목록을 만들 수있는 몇 가지 일반적인 방법이 있습니다. < 그리드 >

장점

: 자동 크기 조정 열 및 행의 폭이
단점 : 행/열을 삽입하는 쉬운 방법 중 하나 VS 또는 [정지!] 혼합, 잠재적으로 지저분한 XAML, 조심하지 않으면 첨부 된 속성의 톤, 여백을 각 컨트롤에 설정해야하며 그리드는 모든 것을 의미하며이 목적으로 설계되지 않았습니다!

XAML Powertools (video 참조)과 같이 모든 필드를 수동으로 번호를 다시 매기 지 않고 행과 열을 삽입하는 편리한 도구가 있음을 알고 있습니다. 하지만 내 생각에 아직 서투른 (동시에 생명의 은인 임에도 불구하고.) 중첩 < StackPanel의 > 컨트롤

<Grid Grid.Row="6" Grid.Column="1"> 

    <Grid.RowDefinitions> 
     <RowDefinition Height="Auto" /> 
     <RowDefinition Height="Auto" /> 
    </Grid.RowDefinitions> 

    <Grid.ColumnDefinitions> 
     <ColumnDefinition Width="Auto" /> 
     <ColumnDefinition Width="Auto" /> 
    </Grid.ColumnDefinitions> 

    <!-- Name --> 
    <TextBlock Text="Name:" Grid.Row="0" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right"/> 
    <TextBox Name="txtName" Grid.Row="0" Grid.Column="1" Width="100" Margin="5,5,0,0"/> 

    <!-- Address --> 
    <TextBlock Text="Address:" Grid.Row="1" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right"/> 
    <TextBox Name="txtAddress" Grid.Row="1" Grid.Column="1" Width="100" Margin="5,5,0,0"/> 

</Grid> 

(이것은 내가 항상 끝날 것 같다 무엇인가 사용)

장점 : 매우 쉽게 항목을 재정렬하기 쉽고 비교적 깨끗함 XAML
단점 : 레이블 컬럼의 폭을 알고 각 항목에 설정할 필요는 여전히 마진 DATAFORM

장점

<StackPanel> 

    <!-- Name --> 
    <StackPanel Orientation="Horizontal"> 
     <TextBlock Text="Name:" Width="60" VerticalAlignment="Center" TextAlignment="Right"/> 
     <TextBox Name="txtName" Width="100" Margin="5,5,0,0"/> 
    </StackPanel> 

    <!-- Address --> 
    <StackPanel Orientation="Horizontal"> 
     <TextBlock Text="Address:" Width="60" VerticalAlignment="Center" TextAlignment="Right"/> 
     <TextBox Name="txtAddress" Grid.Row="1" Grid.Column="1" Width="100" Margin="5,5,0,0"/> 
    </StackPanel> 

</StackPanel> 

으로 엉망이 필요합니다 편집, 다른 편집 상태에 대한 다른보기 등을 처리합니다.
단점 : 여전히 preview 품질 금지 D, 당신이 항목

  <dataform:DataForm x:Name="dataForm" Width="350" ItemsSource="{Binding}" HorizontalAlignment="Left" MaxWidth="500" Margin="4" Grid.Column="1"/> 

의 간단한 목록을 필요로하는 대부분의 시간을 너무 무거운는 http://www.silverlightshow.net/items/Creating-Rich-Data-Forms-in-Silverlight-3-Customization.aspx

내가 원하는 무엇

하세요!

Blend에서 여전히 작동하는 그리드를 원하지만 첨부 된 속성을 사용하여 레이블의 텍스트를 쉽게 설정할 수 있습니다. 또는 '최상의'XAML 방식이 무엇이든간에. 여러 열을 허용하는 것은 좋지만 아마 훨씬 더 복잡 할 것입니다.

장점 : 없음 아직 : 용이 한 곳에서
단점을 항목, 깨끗한 XAML 설정 '의 cellpadding'을 재정렬!

<LabelledGrid CellPadding="5" LabelStyle="{StaticResource labelStyle}> 

    <TextBox LabelledGrid.Label="Name" Name="txtName" /> 
    <TextBox LabelledGrid.Label="Address" Name="txtAddress" /> 

</LabelledGrid> 

아니면

<LabelledGrid CellPadding="5" LabelStyle="{StaticResource labelStyle}> 

    <LabelledGrid.GridItem> 
     <LabelledGrid.Label> 
      Name: 
     </LabelledGrid.Label> 
     <TextBox Name="txtName" /> 
    </LabelledGrid.GridItem> 

    <LabelledGrid.GridItem> 
     <LabelledGrid.Label> 
      Address: 
     </LabelledGrid.Label> 
     <TextBox Name="txtAddress" /> 
    </LabelledGrid.GridItem> 

</LabelledGrid> 

내가 LabelledGrid을 설명하고있어 방법과 같은 기존의 컨트롤이 있습니까 - 또는 내가 이것을 만드는 방법에 대해 어떻게 가야하나요?

+0

장점을 내 목록/각 항목에 대한 단점을 편집 주시기 바랍니다 -이 질문에 속는을보고 싶어요. 방금 –

답변

1

TextBox 템플릿을 변경하고 태그를 레이블로 설정하는 것처럼 간단한 작업을 수행 할 수 있습니다. 당신이 태그 대신 헤더 속성을 사용하는 유사한 템플릿으로 HeaderedContentControl을 사용할 수있는보다 구성 솔루션을 원하는 경우

<StackPanel> 
    <TextBox Template="{StaticResource LabeledTextBox}" Tag="Name"/> 
    <TextBox Template="{StaticResource LabeledTextBox}" Tag="Title"/> 
    <TextBox Template="{StaticResource LabeledTextBox}" Tag="Description"/> 
</StackPanel> 

과 :

<ControlTemplate TargetType="{x:Type TextBox}" x:Key="LabeledTextBox"> 
    <Grid> 
     <Grid.ColumnDefinitions> 
      <ColumnDefinition Width="100"/> 
      <ColumnDefinition/> 
     </Grid.ColumnDefinitions> 

     <TextBlock Text="{TemplateBinding Tag}" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="5,0"/> 

     <Border x:Name="Bd" Grid.Column="1" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="true"> 
      <ScrollViewer x:Name="PART_ContentHost" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/> 
     </Border> 
    </Grid> 
    <ControlTemplate.Triggers> 
     <Trigger Property="IsEnabled" Value="false"> 
      <Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/> 
      <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/> 
     </Trigger> 
    </ControlTemplate.Triggers> 
</ControlTemplate> 

지금 당신은 단지 StackPanel에 당신의 텍스트 상자를 넣을 수 있습니다 PART_ContentHost ScrollViewer 대신 ContentPresenter가 있습니다. 이것에 대한 사용법은 GridItem 예제가 보여주는 것과 유사 할 것입니다. 각 항목은 TextBox를 내용으로 선언합니다. 또한 레이블의 경우 DataTemplates 및 비 텍스트 콘텐츠를 사용할 수 있습니다.

+0

덕분에 찾지 못했습니다. 존. 나는 'HeaderedContentControl'을 사용한다는 아이디어가 마음에 든다. 네, 저는 좀 더 일반적인 것을 찾고 있었지만 저는 또한 여기 저기에있는 모든 가능성을 찾고 있습니다 - 자신과 다른 사람들을 돕기 위해서. 내가 뭔가를 놓치고있는 것 같은 기분이 들지만 내가 궁금해하는 것은 내가 궁금해하는 것은 격자의 확장 또는 완전히 다른 무언가의 자동 번호 매기기이다. –

2

여기 처리 방법은 다음과 같습니다. 각각 개체를 내보기 모델에 생성합니다. 각각의 개체는 LabelValue 속성을 나타냅니다. 그런 다음이 작업을 수행합니다.

<DataTemplate DataType="{x:Type local:Field}"> 
    <Grid> 
     <Grid.ColumnDefinitions> 
     <ColumnDefinition SharedSizeGroup="Label"/> 
     <ColumnDefinition SharedSizeGroup="Value"/> 
     </Grid.ColumnDefinitions> 
     <Label Content="{Binding Label}"/> 
     <TextBox Grid.Column="1" Text="{Binding Value, Mode=TwoWay}"/> 
    </Grid> 
</DataTemplate> 

<ItemsControl Grid.IsSharedSizeScope="True" ItemsSource="{Binding FieldCollection}"/> 

이렇게하면 XAML에서 필드 순서 지정 문제가 발생합니다. 필드는 FieldCollection에 추가 한 순서대로 표시됩니다. 이 방법을 사용하면 개별 필드의 서식을 세부적으로 제어 할 수 없으며 XAML에서 레이블을 유지 관리 할 수 ​​없습니다 (부적절한 작업을 수행하지 않고).하지만 필요한 것이 아닌 경우 문제를 간단하게 처리 할 수 ​​있습니다 .

+0

+1 내가 이것을 파헤 치면 부모가있는 필드 콜렉션의 컬렉션을 만들 수도있다. 컬렉션 유형은 horriontont 배열 하향으로 그려진 목록의 컬렉션을했다. –

1

Dr. WPF의 "'I' is for Item Container"기사를 읽은 후에 나는 이것을 시도해 보았습니다. 아직은 거칠지 만 법안에 어울리는 것 같아요. 아마 WPF를 많이 아는 사람이 나를 향상시킬 수있을 것입니다. 퇴비의 우울을 많이입니다

<Style x:Key="NamedControls" TargetType="{x:Type ListBox}"> 
    <Setter Property="BorderThickness" Value="0"/> 
    <Setter Property="Grid.IsSharedSizeScope" Value="True"/> 
    <Setter Property="ItemContainerStyle"> 
    <Setter.Value> 
     <Style TargetType="{x:Type ListBoxItem}"> 
     <Setter Property="Focusable" Value="False"/> 
     <Setter Property="Template"> 
      <Setter.Value> 
      <ControlTemplate TargetType="{x:Type ListBoxItem}"> 
       <Grid> 
       <Grid.ColumnDefinitions> 
        <ColumnDefinition SharedSizeGroup="NamedControls" Width="Auto"/> 
        <ColumnDefinition/> 
       </Grid.ColumnDefinitions> 
       <Label Content="{Binding Tag}" Padding="5 3"/> 
       <ContentPresenter Grid.Column="1"/> 
       </Grid> 
      </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
     </Style> 
    </Setter.Value> 
    </Setter> 
</Style> 

을,하지만 당신은 한 번만 필요 : 당신의 Window.Resources 또는 App.Resources에서

다음을 추가합니다. 당신의 이름/제어 그룹을 원할 때마다 그런 다음, 바로이 작업을 수행 :

<ListBox Style="{StaticResource NamedControls}"> 
    <TextBox Tag="Name:"/> 
    <TextBox Tag="Address:"/> 
    <TextBox Tag="City:"/> 
</ListBox> 

는 자동으로 라벨 길이가 서로 다른 경우에도 컨트롤을 각 컨트롤의 왼쪽에있는 태그를 보여줍니다 및 선입니다.

일부 노트 :

  • 예는, 정말옵니다 대신 ItemsControl에이어야한다 -하지만 당신은 ItemsControl에 내부 <TextBox/>를 넣어 경우, ItemsControl에의 자식 컨트롤이된다, 그래서이 스타일링 기술을 더 이상 공장. 대신 Items 컬렉션의 요소가되어야합니다.ListBox에는이 문제가 없습니다. 내부에 넣은 내용은 ListBoxItem에 래핑 된 후 Items에 자동으로 추가됩니다. ListBoxItem은 적절하게 스타일을 지정할 수 있습니다.
  • ListBox의 템플릿에있는 항목으로 인해 전체 컨트롤 그룹 주위에 1 픽셀의 빈 여백이 있습니다. ListBox의 테두리를 해제하고 포커스를 얻지 못하도록 할 수는 있었지만 그 한계에 대해 어떻게해야할지 모르겠습니다.
  • 정말 모두가 (리스트 박스 템플릿에서 모든 문제를 해결할 것이다) 자신의 ItemsControl에 자손에 싸서해야하지만, 나는 그것을 설치하고 실행하는 사용자 지정 컨트롤 및 기본 스타일에 대해 충분히 알지 못한다. 또한 태그를 사용하는 대신 레이블에 대해 연결된 속성을 정의 할 수 있습니다.
+0

+1 제품 이미지 대신 목록 상자에서 심슨 문자를 사용하는 기사를 참조하십시오. –

관련 문제