2011-07-01 33 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");