1

我正在使用 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; }
    

    }

在我提出我的问题之前,我在这里有一些额外的属性是不需要的。现在我只想显示 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>
    

因此,如果我设置 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)。任何想法都会很棒。

谢谢,

杰明·罗斯

4

1 回答 1

1

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

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

和:

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

它不仅动态加载您的内容,而且您可以拉伸宽度,这与 ItemsControl 不同。

于 2010-08-11T18:49:59.693 回答