2011-07-01 35 views
2

我想使用Caliburn.Micro约定从Silverlight和WPF工具包的手风琴控制:Caliburn.Micro约定手风琴和AccordionItem

查看:

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

视图模型:

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

默认情况下,卡利结合在手风琴的的ItemsSource元素融入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的头要么绑定到的显示名称AccItemViewModel(IScreen)或在AccItemViewModel上具有Header视图模型属性。 AccordionItem具有HeaderProperty和HeaderTemplateProperty,但我无法弄清楚如何将约定应用于这些。

回答

2

查看源代码下的WPF TabControl约定。这应该让你走上正确的道路。

2

由于它的出现,手风琴的确是极其相似的TabControl,并在我的问题的片段缺失的一块是

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

这里是为了方便您完整的约定(BTW这个代码可以推广对于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");