2012-03-13 6 views
0

StackPanel 또는 Grid (가변 행 수로, 대신 StackPanel을 고려해야 함) 중 하나에서 하위를 레이아웃하는 사용자 정의 구성 요소를 작성하고 싶습니다. 항목은 몇 가지 구성 (일부 레이블 및 텍스트 상자)을 표시하기 위해 몇 가지 컨트롤을 기반으로 일부 구성을 보유하는 사용자 지정 요소/개체입니다.사용자 정의 하위 요소가있는 ItemsControl

이상적으로는, 성분 (SpecializedCustomPanelItemCustomPanelItem의 하위 유형 임)과 같이 어떻게 든 사용해야합니다

<CustomPanel> 
    <CustomPanelItem Param1="value A" Param2="value B">Text</CustomPanelItem> 
    <CustomPanelItem Param1="value C">Other text</CustomPanelItem> 
    <SpecializedCustomPanelItem>More text</SpecializedCustomPanelItem> 
    <!-- The number of items is variable --> 
</CustomPanel> 

지금 잠시 동안 ItemsControl에 읽은는, 그것은 오히려 잘 내 요구에 맞는 . 항목의 유형을 간단하게 만들고 ItemsControl 내부에서 사용할 수있는 데이터 템플릿을 만듭니다. 그럼 이미 벌금을 내야합니다.

그러나 ItemsControl의 항목에 특정 유형 (예 : CustomPanelItem 또는 하위 유형)의 항목이 필요합니다. 실제로 ItemsControlComboBox 또는 MenuItem과 같이 사용자를 허용하지만 실제로는 모든 하위 유형을 허용하고 필요한 경우 항목 컨테이너에 래핑하는 것으로 나타났습니다.

ItemsControl이 실제로 내가 원하는 것일까 생각합니다. 대부분의 컨트롤이 구현하는 선택이나 스크롤 같은 "멋진"것들을 원하지 않기 때문입니다. 실제로는 해당 컴포넌트를 자동으로 생성하고 레이아웃을 Grid/StackPanel에 레이아웃하는 공통 패턴에 대한 간단한 인터페이스 만 빌드하려고합니다.

그래도 ItemsControl을 사용해야하나요, 아니면 더 많은 맞춤 구성 요소를 만들어야합니까? 당신이 당신의 품목을 보유하고, 각 항목을 그리는 방법을 정의 할 ItemContainerTemplate을 설정합니다 패널의 종류를 정의하는 ItemsPanelTemplate있어 설정할 수 있습니다 ItemsControl

에 대한

+0

뷰 모델에서 항목을 바인딩 할 예정입니까? 아니면 xaml에 정적으로 선언되어 있습니까? – NVM

+0

그들은 정적으로 선언되지만 내용 (생성 된 텍스트 상자 안의 값)은 아마도 바인딩을 가져올 것입니다. – poke

+0

그런 경우 컴파일 타임에 어떤 유형을 패널에 추가했는지 알 수 있습니다. 컴파일 타임에 괜찮 으면 런타임에 잘못 될 가능성이 없습니다. 이렇게 체크는 런타임 검사가 아닌 단위 테스트에 적합한 경우가 아닙니까? – NVM

답변

1

이 완벽 소리.

항목이 그려 다르게 그들이 유형에 근거해야한다, 내가 암시 DataTemplates를 사용하는 대신에 당신은 아마 대신 동적으로 생성 된 그리드를 사용하고 싶다고 언급 ItemContainerTemplate

<Window.Resources> 
    <DataTemplate DataType="{x:Type my:BasePanelItem}"> 
     <my:CustomPanelItem Param1="{Binding Param1}" Param2="{Binding Param2}" Content="{Binding SomeValue}" /> 
    </DataTemplate> 
    <DataTemplate DataType="{x:Type my:SpecializedPanelItem}"> 
     <my:SpecializedCustomPanelItem Content="{Binding SomeValue}" /> 
    </DataTemplate> 
</Window.Resources> 


<ItemsControl ItemsSource="{Binding MyItems}"> 
    <!-- ItemsPanelTemplate --> 
    <ItemsControl.ItemsPanel> 
     <ItemsPanelTemplate> 
      <my:CustomPanel /> 
     </ItemsPanelTemplate> 
    </ItemsControl.ItemsPanel> 
</ItemsControl> 

를 설정하는 게 좋을 것 StackPanel도 있습니다. 그럴 경우 내 블로그에 게시 한 GridHelpers에 관심이있을 수 있습니다. 이건 정말 사용자 지정 구성 요소를 필요로 당신은 당신이하지 않는이 경우 ItemsPanelTemplate

<ItemsControl ItemsSource="{Binding MyCollection}"> 
    <!-- ItemsPanelTemplate --> 
    <ItemsControl.ItemsPanel> 
     <ItemsPanelTemplate> 
      <Grid local:GridHelpers.RowCount="{Binding RowCount}" 
        local:GridHelpers.ColumnCount="{Binding ColumnCount}" /> 
     </ItemsPanelTemplate> 
    </ItemsControl.ItemsPanel> 

    <!-- ItemContainerStyle --> 
    <ItemsControl.ItemContainerStyle> 
     <Style> 
      <Setter Property="Grid.Column" Value="{Binding ColumnIndex}" /> 
      <Setter Property="Grid.Row" Value="{Binding RowIndex}" /> 
     </Style> 
    </ItemsControl.ItemContainerStyle> 
</ItemsControl> 
3

Grid에 열/행의 수를 결합 할 수있다. ItemsPanel 유형을 필요한 유형으로 변경하고 항목에 대해 여러 개의 템플릿을 사용하여 트릭을 수행해야합니다.

그러나 제목에서 질문에 대답 : 당신은 단지 아이템의 특정 유형을 수락 제어 항목을 강제하려는 경우, 당신은

을 만들어야합니다. CustomItemsControl
b.기억이 다른 유형을 허용하지 않도록 ItemsControl을 강제해야한다 제공하는 경우는 속성

[StyleTypedProperty(Property = "ItemContainerStyle", StyleTargetType = typeof(CustomItemsControlItem))] 

를 선언해야 CustomItemsControl에 대한 CustomItemsControlItem 그런

그런 다음 당신은 또한

protected override DependencyObject GetContainerForItemOverride() 
    { 
     return new CustomItemsControlItem(); 
     // You can throw an exception here 
    } 

    protected override bool IsItemItsOwnContainerOverride(object item) 
    { 
     return item is CustomItemsControlItem; 
    } 

필요합니다 아이들로 추가되어 예외를 던져야합니다. 그런 다음 XAML에 항목을 추가 할 때 설정할 수있는 DependencyProperties를 정의하여 CustomItemsControlItem 내부에서 마법을 사용할 수 있습니다.

그러나 올바르게 표시하려는 ViewModel에 여러 유형이있는 경우 올바른 방법은 여전히 ​​ViewModel 유형을 대상으로하는 CustomItemsControlItem에 대한 여러 템플릿을 제공하는 것입니다.

희망이 도움이됩니다.

+0

+1, 그 항목은'Window' 또는'Popup' 일 수있는 우리의 "Open Windows Preview Carousel"컨트롤에 사용했습니다. –

관련 문제