具有动态内容的Silverlight手风琴控制

时间:2010-02-19 18:46:33

标签: silverlight-3.0 silverlight-toolkit

我正在使用Silverlight Toolkit的Accordion控件。我想创建一个控件列表,我可以加载到手风琴中并在需要时动态替换。所以这就是我所做的:

  1. 创建一个类来保存每个手风琴项目的标题和内容。

    公共类AccordionViewItem {     public AccordionViewItem()     {         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; }
    

    }

  2. 我在这里有一些额外的属性,直到我提出我的问题才需要。现在我只想显示Header和ItemsControlContext属性。

    1. 创建了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>
      
    2. 因此,如果我设置了datacontext并发送了一个AccordionViewItems列表,我可以获得一个正常运作的Accordion,但我真的想让我的AccordionView Item看起来像:

      public class AccordionViewItem
      {
          public AccordionViewItem()
          {
              Content = new StackPanel();
          }
      
          public string Header { get; set; }
          public FrameworkElement Content { get; set; }
      }
      

      所以我创建了一个名为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>
      

      代码背后:

      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; }
          }
      }
      

      然后更改Accordion以使用新控件:

          <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>
      

      但是在ItemControl构造函数运行后出现以下错误:

      AG_E_PARSER_BAD_PROPERTY_VALUE [专栏:1职位:197]

      知道我为什么会收到此错误?还有另一种动态加载控件的方法吗?我正试图尽可能少地使用代码中的代码(MVVM)。任何想法都会很棒。

      谢谢,

      Jamin Roth

1 个答案:

答案 0 :(得分:1)

我找到了一个简单的解决方案。您可以使用ContentPresenter。所以你可以像自定义控件那样使用它。所以你可以替换:

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

使用:

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

它不仅动态加载你的内容,而且你可以像ItemsControl一样拉伸宽度。