2009-09-29 3 views
0

J'ai créé un contrôle personnalisé que j'insérer dans ma fenêtre avec le code suivantpermettant d'ajouter des éléments à une liste XAML

<controls:ListExpander Text="Class Diagrams"></controls:ListExpander> 

Le contrôle en question contient plusieurs sous-contrôles, entre autres, une liste. Comment créer la configuration, afin que je puisse spécifier les éléments qui devraient être ajoutés à la liste? Finalement, je suis à la recherche de l'architecture suivante

<controls:ListExpander Text="Class Diagrams"> 
    <SomeItem>data<SomeItem> 
    <SomeItem>data<SomeItem> 
    <SomeItem>data<SomeItem> 
    <SomeItem>data<SomeItem> 
</controls:ListExpander> 

auquel cas les objets SomeItem devraient être ajoutés à la liste dans le ListExpander:

<ListBox Name="lstItems" Background="LightGray"> 
     <ListBox.Items> 
      // Items should go here 
     </ListBox.Items> 
    </ListBox> 

Je suis tout à fait nouveau pour WPF, mais je suppose c'est quelque chose dans le sens de la création d'une collection de dépendances sur ListExpander qui prend l'objet du type SomeItem?

Modifier: Permettez-moi de clarifier un peu. Je veux simplement pouvoir donner au contrôle quelques arguments qu'il peut traduire en items dans la listbox contenue dans le contrôle.

Répondre

1

Avez-vous créé votre classe pour ListExpander? Vous pouvez très simplement hériter de toutes les fonctionnalités d'un ItemsControl. Voici un exemple de classe que j'ai créé pour que vous le modélisiez après.

CLASSE

using System.Windows.Controls; 

namespace ListExpanderSample 
{ 
    public class ListExpander : ItemsControl 
    { 
     static ListExpander() 
     { 
      /* Required logic goes here */ 
     } 
    } 
} 

APPLICATION

<Grid> 
    <Grid.Resources> 
     <Style x:Key="{x:Type local:ListExpander}" TargetType="{x:Type local:ListExpander}"> 
      <Setter Property="Template"> 
       <Setter.Value> 
        <ControlTemplate TargetType="{x:Type local:ListExpander}"> 
         <Border Background="Transparent" > 
          <ScrollViewer Focusable="False" HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto"> 
           <ItemsPresenter /> 
          </ScrollViewer> 
         </Border> 
        </ControlTemplate> 
       </Setter.Value> 
      </Setter> 
     </Style> 
    </Grid.Resources> 
    <local:ListExpander> 
     <local:ListExpander.Items> 
      <Button Content="Button 1"/> 
      <TextBox Text="TextBox 1"/> 
      <Button Content="Button 2"/> 
      <TextBox Text="TextBox 2"/> 
     </local:ListExpander.Items> 
    </local:ListExpander> 
</Grid> 

SCREENSHOT

Sample ListExpander http://lh4.ggpht.com/_jvamiP47SsA/SsWM6xN_3BI/AAAAAAAAAkg/tZUWxzi9wVI/s800/Window1.jpg

J'espère que cela vous a aidé, Qua.

1

Je suppose que votre contrôle contient plus que ces enfants que vous cherchez à ajouter, n'est-ce pas? Donc, j'irais en ajoutant une propriété à votre classe de contrôle comme celui-ci:

private ObservableCollection<UIElement> _items = new ObservableCollection<UIElement>(); 
public ObservableCollection<UIElement> Items 
{ 
    get { return this._items; } 
} 

Ensuite, dans vos commandes vous TEMPLATE bind votre ListBox à cette collection

<ListBox Name="lstItems" Background="LightGray" ItemsSource="{Binding Items}"> 
</ListBox> 

De cette façon, vous serez en mesure de l'utiliser comme ceci:

<controls:ListExpander Text="Class Diagrams"> 
    <controls:ListExpander.Items> 
    <SomeItem>data<SomeItem> 
    <SomeItem>data<SomeItem> 
    <SomeItem>data<SomeItem> 
    <SomeItem>data<SomeItem> 
    </controls:ListExpander.Items> 
</controls:ListExpander> 

pour pouvoir l'utiliser sans <controls:ListExpander.Items> décorer votre attribut classe avec [ContentProperty("Items")].

+0

La liaison entre Items et lstItems ne semble pas fonctionner. Les objets SomeItem sont en fait ajoutés à _items, mais pas à la listbox. –

+0

Peut-être que vous devez définir DataContext dans votre constructeur de contrôles pour la liaison au travail. Quelque chose comme ceci.DataContext = this; Ou utilisez TemplateBinding au lieu de Binding ou utilisez une version plus longue de l'expression Binding spécifiant RelativeSource. De toute façon, le principe est là et vous avez juste besoin de trouver une anomalie manquante dans mon exemple de code. –

0

Il existe un moyen simple de le faire.Ajouter une propriété de type ItemCollection à votre classe de contrôle comme celui-ci:

public ItemCollection Items{ 
    get{ 
     return innerItems.Items; 
    }set{ 
     innerItems.Items.Clear(); 
     foreach (var item in value){ 
      innerItems.Items.Add(item); 
     } 
    } 
} 

où innerItems est juste un ItemsControl dans votre XAML (comme ça):

<UserControl x:Class="TestApp.ItemsExtender" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Height="300" Width="300"> 
    <StackPanel> 
     <Label Content="Control Label" /> 
     <ItemsControl x:Name="innerItems" /> 
    </StackPanel> 
</UserControl> 

puis ajoutez un attribut à votre classe de contrôle comme ceci:

[ContentProperty("Items")] 
public partial class ItemsExtender : UserControl 
{...} 

ceci indiquera que les éléments XAML par défaut doivent être attribués à votre propriété Items, et votre propriété Items les utilisera pour remplir votre collection de liste intérieure. Vous pouvez le consommer comme ceci:

<this:ItemsExtender> 
    <Label Content="item1" /> 
    <Label Content="item2" /> 
    <Label Content="item3" /> 
</this:ItemsExtender> 

Vous pouvez étendre cet exemple avec des convertisseurs de type pour aider à ajouter des choses arbitraires aux propriétés de collecte et de dépendance à l'appui de liaison, mais vous devriez commencer.

J'espère que ça aide!

Questions connexes