2010-06-28 14 views
25

Nadal wygłupiaj się z WPF i ucz się jak idę. Próbuję teraz zbudować dynamiczne grupowanie kontrolek (głównie przycisków, ale może to być CheckBox i inne).WrapPanel jako ItemPanel dla ItemsControl

Nie miałem pojęcia, jaki był najlepszy sposób, aby to zrobić, więc próbowałem stworzyć styl ItemsControl, a następnie dodać elementy do ItemsPresenter wewnątrz WrapPanel. Wkrótce zrozumiałem, że przedmioty nie będą się zawijać, ponieważ skutecznie nie znajdowały się wewnątrz WrapPanel, chyba że ustawię je jako ItemsHost. W ten sposób:

<Style x:Key="ButtonPanelGroup" TargetType="{x:Type ItemsControl}"> 
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="{x:Type ItemsControl}"> 
       <Border CornerRadius="5" 
         BorderBrush="{StaticResource DarkColorBrush}" 
         BorderThickness="1" 
         Margin="5"> 
        <Grid> 
         <Grid.RowDefinitions> 
          <RowDefinition /> 
          <RowDefinition Height="Auto" /> 
         </Grid.RowDefinitions> 

         <WrapPanel IsItemsHost="True" FlowDirection="LeftToRight"> 
          <ItemsPresenter /> 
         </WrapPanel> 

         <ContentPresenter ContentSource="Name" Grid.Row="1" /> 

        </Grid> 
       </Border> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 

Należy zauważyć, że jest to praca w toku i istnieje wiele efektów stylizacyjnych, które wciąż muszę wprowadzić. Tutaj używam go:

<UniformGrid Rows="1"> 
    <ItemsControl Name="Group1" Style="{StaticResource ButtonPanelGroup}"> 
     <Button>Button1</Button> 
     <Button>Button2</Button> 
     <CheckBox>TickBox</CheckBox> 
    </ItemsControl> 

    <ItemsControl Name="Group2" Style="{StaticResource ButtonPanelGroup}"> 
     <Button>Button3</Button> 
     <Button>Button4</Button> 
     <Button>Button5</Button> 
    </ItemsControl> 

    <ItemsControl Name="Group3" Style="{StaticResource ButtonPanelGroup}"> 
     <Button>Button6</Button> 
     <Button>Button7</Button> 
     <Button>Button8</Button> 
    </ItemsControl> 
</UniformGrid> 

Należy również zauważyć tutaj, że jest nadal w toku, jak UniformGrid nie byłoby sposobu, aby przejść tutaj i również marże mogą być ból (czy są jakieś marginesy, które pokrywają się?) więc wejście tam byłoby docenione.

Teraz prawdziwy problem. To nie działa pojawia się błąd:

'ItemsPresenter' object cannot be added to 'WrapPanel'. Cannot explicitly modify Children collection of Panel used as ItemsPanel for ItemsControl. ItemsControl generates child elements for Panel. Error at object 'System.Windows.Controls.ItemsPresenter'.

Więc co jest najlepszym sposobem, aby zrobić coś takiego (chciałbym, aby móc po prostu wyrzucić przycisków i innych elementów sterujących w ItemControl i linia się naprawdę ładne) . Czy byłoby lepiej umieścić Kontrolę w jakiejś kolekcji i powtórzyć?

Chciałbym to ładnie zrobić, ale moje umiejętności WPF wciąż brakuje. Czy są jakieś książki WPF, które uczą czegoś więcej niż podstawy i pokazują, jak profesjonaliści naprawdę by to robili?

Odpowiedz

39

Czasami warto spojrzeć na nieruchomości ItemsPanel:

Gets or sets the template that defines the panel that controls the layout of items.

Przykład:

<ItemsControl> 
    <ItemsControl.ItemsPanel> 
     <ItemsPanelTemplate> 
      <WrapPanel /> 
     </ItemsPanelTemplate> 
    </ItemsControl.ItemsPanel> 
</ItemsControl> 

I można ustawić go w stylu następująco:

<Style TargetType="ItemsControl"> 
    <Setter Property="ItemsPanel"> 
     <Setter.Value> 
      <ItemsPanelTemplate> 
       <WrapPanel /> 
      </ItemsPanelTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 
+0

To działa, ale nie chcę ustawić go w stylu zamiast w każdym ItemControl. Pomyślałem, że było to możliwe z właściwością IsItemsHost, ale nie działa. Czy to jedyny sposób? –

+0

Zaktualizowana odpowiedź ze stylem dla ItemsControl – Arcturus

+0

Ah, oczywiście, mogę również dodać do tego stylu, dziękuję. Jeśli masz czas, możesz spojrzeć na 2 inne pytania, które wciąż są nierozwiązane. http://stackoverflow.com/questions/3118266/wpf-datatemplate-property-set-at-content http://stackoverflow.com/questions/3004967/how-to-reuse-layouts-in-wpf –

3

Nie zapomnij o definicji właściwości wskazówki IsItemsHost = "True". W przeciwnym razie przedmioty ItemsControl nie będą wyświetlać twoich przedmiotów.

<ListBox ItemsSource="{Binding MyItemsSource}"> 
     <ItemsControl.ItemsPanel> 
      <ItemsPanelTemplate > 
       <WrapPanel IsItemsHost="True"/> 
      </ItemsPanelTemplate> 
     </ItemsControl.ItemsPanel> 
    </ListBox> 
Powiązane problemy