2010-02-19 5 views
1

J'utilise le contrôle accordéon de Silverlight Toolkit. Je voulais créer une liste de contrôles que je pourrais charger dans l'accordéon et remplacer à la volée si nécessaire. Voici donc ce que j'ai fait:Contrôle d'accordéon Silverlight avec contenu dynamique

  1. Créez une classe pour contenir l'en-tête et le contenu de chaque élément accordéon.

    public class AccordionViewItem { AccordionViewItem public() { ItemsControlContent = new ObservableCollection(); ItemsControlContent.Add (new StackPanel()); }

    public string Header { get; set; } 
    public FrameworkElement Content 
    { 
        get { return ItemsControlContent[0]; } 
        set { ItemsControlContent[0] = value; } 
    } 
    
    public ObservableCollection<FrameworkElement> ItemsControlContent { get; set; } 
    

    }

J'ai quelques propriétés supplémentaires ici qui ne sont pas nécessaires jusqu'à ce que je présente mon problème. Pour l'instant je voulais juste montrer les propriétés Header et ItemsControlContext.

  1. Créé le contrôle Accordian.

    <layoutToolkit:Accordion x:Name="AccordionHost" ItemsSource="{Binding Path=Panels}" SelectionMode="One" VerticalAlignment="top" HorizontalAlignment="Center" > 
        <layoutToolkit:Accordion.ItemTemplate> 
         <DataTemplate> 
          <StackPanel> 
           <TextBlock Text="{Binding Header}" /> 
          </StackPanel> 
         </DataTemplate> 
        </layoutToolkit:Accordion.ItemTemplate> 
        <layoutToolkit:Accordion.ContentTemplate> 
         <DataTemplate> 
          <ItemsControl ItemsSource="{Binding Path=ItemsControlContent}" /> 
         </DataTemplate> 
        </layoutToolkit:Accordion.ContentTemplate> 
    </layoutToolkit:Accordion> 
    

Donc, si je mis la datacontext et envoyer dans une liste de AccordionViewItems je peux obtenir un fonctionnement d'accordéon, mais je voulais vraiment avoir l'air mon AccordionView article comme:

public class AccordionViewItem 
{ 
    public AccordionViewItem() 
    { 
     Content = new StackPanel(); 
    } 

    public string Header { get; set; } 
    public FrameworkElement Content { get; set; } 
} 

Alors J'ai créé un contrôle personnalisé appelé ItemControl:

<UserControl x:Class="ECAPortal.Client.Common.Controls.ItemControl" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Height="400" 
    Width="300" > 
    <Grid x:Name="LayoutRoot" Background="White"> 
     <ItemsControl x:Name="itemsControlLoader" /> 
    </Grid> 
</UserControl> 

code Derrière:

public partial class ItemControl : UserControl 
{ 
    private ObservableCollection<FrameworkElement> m_controls = new ObservableCollection<FrameworkElement>(); 

    public ItemControl() 
    { 
     m_controls.Add(new StackPanel()); 

     InitializeComponent(); 

     this.Loaded += new RoutedEventHandler(ItemControl_Loaded); 
    } 

    void ItemControl_Loaded(object sender, RoutedEventArgs e) 
    { 
     itemsControlLoader.ItemsSource = m_controls; 
    } 

    public FrameworkElement ItemSource 
    { 
     get { return m_controls[0]; } 
     set { m_controls[0] = value; } 
    } 
} 

changer ensuite l'accordéon à utiliser la nouvelle commande:

<layoutToolkit:Accordion x:Name="AccordionHost" ItemsSource="{Binding Path=Panels}"  SelectionMode="One" Margin="0,50" Width="740" VerticalAlignment="top"  HorizontalAlignment="Center" > 
     <layoutToolkit:Accordion.ItemTemplate> 
      <DataTemplate> 
       <StackPanel> 
        <TextBlock Text="{Binding Header}" /> 
       </StackPanel> 
      </DataTemplate> 
     </layoutToolkit:Accordion.ItemTemplate> 
     <layoutToolkit:Accordion.ContentTemplate> 
      <DataTemplate> 
       <controls:ItemControl ItemSource="{Binding Content}" /> 
      </DataTemplate> 
     </layoutToolkit:Accordion.ContentTemplate> 
    </layoutToolkit:Accordion> 

Mais je reçois l'erreur suivante après le constructeur ItemControl est exécuté:

AG_E_PARSER_BAD_PROPERTY_VALUE [Ligne: 1 Position: 197]

Une idée de pourquoi je reçois cette erreur? Existe-t-il un autre moyen de charger dynamiquement un contrôle? J'essaye d'utiliser aussi peu de code dans le code que possible (MVVM). Toutes les idées seraient géniales.

Merci,

Roth Jamin

Répondre

1

J'ai trouvé une solution simple. Vous pouvez utiliser ContentPresenter. Vous pouvez donc l'utiliser comme le contrôle personnalisé devrait avoir. Ainsi, vous pouvez remplacer:

<controls:ItemControl ItemSource="{Binding Content}" /> 

Avec:

<ContentPresenter Content="{Binding Content}" /> 

non seulement il charge dynamiquement votre contenu, mais vous pouvez étirer la largeur contrairement à la ItemsControl.

Questions connexes