Caliburn.Micro конвенция для Accordion и AccordionItem - PullRequest
2 голосов
/ 01 июля 2011

Я бы хотел использовать условные обозначения Caliburn.Micro для элемента управления Accordion от Silverlight и WPF Toolkits:

View:

<Grid Background="White">
    <Controls:Accordion x:Name="Items"/>
</Grid>

ViewModel:

public class ShellViewModel : IShell
{
    public ShellViewModel()
    {
        Items = new List<AccItemViewModel>
                    {
                        new AccItemViewModel
                            {
                                DisplayName = "header one", 
                                Content = "content one"
                            },
                        new AccItemViewModel
                            {
                                DisplayName = "header two", 
                                Content = "content two"
                            },
                    };
    }

    public IEnumerable<IScreen> Items { get; set; }


    public class AccItemViewModel : Screen
    {
        public string Content { get; set; }
    }

По умолчанию Caliburn связывает элементы в ItemSource Аккордеона с заголовками AccordionItem:


Я добавил соглашение для ContentTemplate Аккордеона:

    private void AddCustomConventions()
    {
        ConventionManager.AddElementConvention<Accordion>
        (Accordion.ItemsSourceProperty, "SelectedItem", "SelectionChanged")
        .ApplyBinding =
        (viewModelType, path, property, element, convention) =>
        {
            if (ConventionManager
            .GetElementConvention(typeof(ItemsControl))
            .ApplyBinding(viewModelType, path, property,
            element, convention))
            {
                element.SetValue(Accordion.ContentTemplateProperty,
                ConventionManager.DefaultItemTemplate);
                return true;
            }
            return false;
        };
    }

, которое достигло следующего:

, но я бы хотел либо связать заголовок AccordionItem с DisplayName объекта AccItemViewModel (IScreen), либо иметь свойство модели представления Header в AccItemViewModel.У AccordionItem есть HeaderProperty и HeaderTemplateProperty, но я не могу понять, как применить к ним соглашения.

Ответы [ 2 ]

2 голосов
/ 07 июля 2011

Как оказалось, Аккордеон действительно очень похож на TabControl, и отсутствующий фрагмент для моего фрагмента был

ConventionManager
  .ApplyHeaderTemplate(accordion, 
     ItemsControl.ItemTemplateProperty, viewModelType);

Вот полное соглашение для вашего удобства (кстати, этот код можно обобщить для нескольких потомков ItemsControl):

        ConventionManager.AddElementConvention<Accordion>(
            ItemsControl.ItemsSourceProperty, 
            "ItemsSource", "SelectionChanged")
            .ApplyBinding = (
                viewModelType, path, property, element, convention) =>
            {
                if (!ConventionManager.SetBinding(
                    viewModelType, path, property, element, convention))
                    return false;

                var accordion = (Accordion)element;
                if (accordion.ContentTemplate == null
                    && property.PropertyType.IsGenericType)
                {
                    var itemType = property
                        .PropertyType
                        .GetGenericArguments()
                        .First();
                    if (!itemType.IsValueType &&
                        !typeof(string).IsAssignableFrom(itemType))
                    {
                        accordion.ContentTemplate = 
                            ConventionManager.DefaultItemTemplate;
                    }
                }

                ConventionManager.ConfigureSelectedItem(
                    element, Selector.SelectedItemProperty, 
                    viewModelType, path);

                if (string.IsNullOrEmpty(accordion.DisplayMemberPath))
                    ConventionManager.ApplyHeaderTemplate(
                        accordion, ItemsControl.ItemTemplateProperty, 
                        viewModelType);

                return true;
            };
        ConventionManager.AddElementConvention<AccordionItem>(
            ContentControl.ContentProperty, 
            "DataContext", "DataContextChanged");
2 голосов
/ 01 июля 2011

Ознакомьтесь с соглашением WPF TabControl под источником. Это должно поставить вас на правильный путь.

...