2010-05-04 114 views
3

我剛剛開始SL世界,並試圖將Caliburn NavigationShell作爲我的出發點。我將解決方案轉換爲SL4並使用主幹中的Caliburn。將SL4 TreeView綁定到使用Caliburn的IGrouping

要創建基本的導航,我有點不確定(好,很),我怎麼能顯示按鈕的原始StackPanel作爲可摺疊Treeview。

我改變ITaskBarItem給自己一個簡單的GroupName屬性

public interface ITaskBarItem : IEntryPoint 
{ 
    BitmapImage Icon { get; } 
    string DisplayName { get; } 
    string GroupName { get;} 
} 

然後,我在ShellViewModel揭露這查看:

public IEnumerable<IGrouping<string, ITaskBarItem>> TaskBarItems 
    { 
     get { return _taskBarItems.GroupBy(t => t.GroupName); } 
    } 

我該怎麼辦XAML標記,使我得到一個簡單的層次?

如何在不使用按鈕的情況下綁定動作?

 
> GroupName 
    DisplayName 
    DisplayName 
    DisplayName 

> GroupName 
    DisplayName 
    DisplayName 
    DisplayName 
    ... 

記住,這是MVVM,所以我不打算使用後面的代碼或事件這樣做...

回答

2

有一對夫婦的困難在這裏。首先,這裏是我的標記:

<ItemsControl x:Name="TaskBarItems"> 
    <ItemsControl.ItemTemplate> 
     <DataTemplate> 
      <StackPanel> 
       <TextBlock Text="{Binding Converter={StaticResource groupName}}" 
          FontWeight="Bold" /> 
       <ItemsControl ItemsSource="{Binding}" 
           Margin="12 0 0 0"> 
        <ItemsControl.ItemTemplate> 
         <DataTemplate> 
          <StackPanel> 
           <TextBlock Text="{Binding DisplayName}" /> 
          </StackPanel> 
         </DataTemplate> 
        </ItemsControl.ItemTemplate> 
       </ItemsControl> 
      </StackPanel> 
     </DataTemplate> 
    </ItemsControl.ItemTemplate> 
</ItemsControl> 

和我的外殼:

public class ShellViewModel : IShell 
{ 
    readonly TaskBarItemViewModel[] taskBarItems; 

    public ShellViewModel() 
    { 
     taskBarItems = new[] 
      { 
       new TaskBarItemViewModel {GroupName = "Animal", DisplayName = "Monkey"}, 
       new TaskBarItemViewModel {GroupName = "Animal", DisplayName = "Cat"}, 
       new TaskBarItemViewModel {GroupName = "Animal", DisplayName = "Dog"}, 
       new TaskBarItemViewModel {GroupName = "Mineral", DisplayName = "Biotite"}, 
       new TaskBarItemViewModel {GroupName = "Mineral", DisplayName = "Phlogopite"}, 
       new TaskBarItemViewModel {GroupName = "Mineral", DisplayName = "Lepidolite"}, 
      }; 
    } 

    public IEnumerable<IGrouping<string, TaskBarItemViewModel>> TaskBarItems 
    { 
     get 
     { 
      return taskBarItems.GroupBy(t => t.GroupName).ToList(); 
     } 
    } 
} 

Calibrun微(釐米)將綁定ItemsControl的,TaskBarItems,按照約定。然而,由於幾個原因,其餘的不會按慣例工作。它在一個DataTemplate中,所以我們通常會使用Bind.Model。但是,它不會在這裏工作,因爲itemscontrol中的每個項目的類型是通用的(IGrouping)。默認約定無法處理爲此查找視圖。所以我們提供了一個內嵌的數據模板。

其次,Key屬性看起來被實現爲顯式接口。這意味着Silverlight無法綁定到它。我做了一個簡單的轉換器結合到組並提取關鍵:

public class GroupNameConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     return ((IGrouping<string,TaskBarItemViewModel>)value).Key; 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 
} 

其次,由於分組本身了IEnumerable我們要嵌套的ItemsControl的ItemsSource時直接綁定。我們不能使用約定,因爲沒有屬性返回項目的IGrouping。 (雖然如果有,我們可能仍然有明確的接口問題。)

關於你的第二個問題。您可以將操作綁定到任何事件。在這裏看到的文檔: http://caliburnmicro.codeplex.com/wikipage?title=All%20About%20Actions&referringTitle=Documentation

+1

對不起,這是你需要它之​​後的4個月。 – 2010-09-08 15:07:09

+1

感謝您提供詳盡的答案,這對其他人來說是有用的,當然,我也學到了很多東西,這些東西將會再次得到體驗:) – Jan 2010-09-09 17:17:39

1

從克里斯托弗的回答值變換器可以概括如下:


public class ExplicitPropertyConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     return value == null ? null : GetPropertyValue(value, (string)parameter); 
    } 

    private static object GetPropertyValue(object target, string name) 
    { 
     return (
       from type in target.GetType().GetInterfaces() 
       from prop in type.GetProperties() 
       where prop.Name == name && prop.CanRead 
       select prop.GetValue(target, new object[0]) 
      ).FirstOrDefault(); 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 
} 

和使用是在這裏:


<TextBlock 
    Text="{ 
     Binding 
     Converter={StaticResource ExplicitPropertyConverter}, 
     ConverterParameter=Key 
    }" 
    /> 

此轉換器支持的任何任何財產接口。更多信息在my blog