2010-05-04 5 views
3

Je ne fais que commencer dans le monde SL et j'essaie d'utiliser le Caliburn NavigationShell comme point de départ. J'ai converti la solution en SL4 et j'utilise Caliburn depuis le coffre.Lier un TreeView SL4 à un groupage IG en utilisant Caliburn

Pour créer la navigation de base, je suis un peu incertain (bien, tout à fait), comment je peux afficher le StackPanel original de boutons comme une vue arborescente pliable.

Je ITaskBarItem changé de posséder simple propriété GroupName

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

, j'expose cela en ShellViewModel à la vue:

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

Comment puis-je faire le balisage XAML pour que je reçois une hiérarchie simple?

Comment lier des actions sans utiliser de boutons?

 
> GroupName 
    DisplayName 
    DisplayName 
    DisplayName 

> GroupName 
    DisplayName 
    DisplayName 
    DisplayName 
    ... 

esprit, c'est MVVM, donc je ne vais pas utiliser le code derrière ou des événements pour le faire ...

Répondre

2

Il y a quelques difficultés ici. Tout d'abord, voici mon code:

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

et mon Shell:

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 Micro (cm) va se lier ItemsControl, TaskBarItems, par convention. Cependant, le reste ne fonctionnera pas par convention pour plusieurs raisons. C'est dans un DataTemplate, donc nous utiliserions habituellement Bind.Model. Cependant, cela ne fonctionnera pas ici car le type de chaque élément dans itemscontrol est générique (IGrouping). Les conventions par défaut ne peuvent pas gérer la recherche d'une vue pour cela. Nous fournissons donc un modèle de données en ligne.

Deuxièmement, la propriété Key semble être implémentée en tant qu'interface explicite. Cela signifie que Silverlight ne peut pas s'y lier. Je fait un convertisseur simple qui se lie au groupe et extrait la clé:

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

Ensuite, puisque le groupe lui-même est le IEnumerable que nous devons lier directement l'ItemsSource de ItemsControl imbriqué. Nous ne pouvons pas utiliser de conventions car il n'y a pas de propriété sur IGrouping qui renvoie les éléments. (Bien que, si c'était le cas, nous aurions probablement encore le problème d'interface explicite.)

En ce qui concerne votre deuxième question. Vous pouvez lier une action à n'importe quel événement. Consultez la documentation ici: http://caliburnmicro.codeplex.com/wikipage?title=All%20About%20Actions&referringTitle=Documentation

+1

Désolé, cela a été 4 mois après que vous en aviez besoin. –

+1

Merci pour la réponse exhaustive, il sera utile à quelqu'un d'autre, à coup sûr et j'ai aussi appris beaucoup de choses qui viendront à portée de main une autre fois :) – Jan

1

Le convertisseur de valeur de la réponse de Christopher peut être généralisée comme ceci:


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

Et l'utilisation est ici:


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

Ce convertisseur prend en charge toute propriété de tout interface. Plus d'infos dans my blog.

Questions connexes