Аккордеонный контроль Silverlight с динамическим контентом - PullRequest
1 голос
/ 19 февраля 2010

Я использую аккордеонный элемент управления Silverlight Toolkit. Я хотел создать список элементов управления, которые я мог бы загрузить в аккордеон и при необходимости заменить на лету. Итак, вот что я сделал:

  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>
    

Поэтому, если я установлю текст данных и отправлю список AccordionViewItems, я смогу получить работающий Accordion, но я действительно хотел, чтобы мой элемент AccordionView выглядел следующим образом:

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

Затем измените Аккордеон, чтобы использовать новый элемент управления:

    <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). Любые идеи будут великолепны.

Спасибо

Джамин Рот

1 Ответ

1 голос
/ 11 августа 2010

Я нашел простое решение. Вы можете использовать ContentPresenter. Таким образом, вы можете использовать его так, как должен иметь пользовательский элемент управления. Таким образом, вы можете заменить:

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

С:

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

он не только загружает ваш контент динамически, но вы можете увеличить ширину в отличие от ItemsControl.

...