2010-10-30 19 views
3

Nous utilisons Caliburn.Micro/Silverlight 4 et la vie est bonne. J'essaie de lier une itemSource d'une combobox à un viewModel, mais cela ne semble pas possible car la combobox est déjà liée à l'élément dataItem de sa propre ligne. La logique qui remplit le combo change avec d'autres données à l'écran, donc je ne peux pas vraiment utiliser une liste statique comme celle que j'ai utilisée.Comment lier silverlight datagrid combo box itemSource à viewModel

Existe-t-il un moyen de lier le répertoire au viewModel en quelque sorte ??? J'ai essayé la liaison d'élément à élément, mais cela ne semble jamais fonctionner dans la grille.

 <Controls:DataGridTemplateColumn x:Name="FooNameCol" Header="Foo" MinWidth="200"> 
      <Controls:DataGridTemplateColumn.CellTemplate> 
       <DataTemplate> 

        <StackPanel> 
         <TextBlock Text="{Binding Path=Foo.ShortName}" 
            Style="{StaticResource DataGridTextColumnStyle}"/> 
        </StackPanel> 

       </DataTemplate> 
      </Controls:DataGridTemplateColumn.CellTemplate> 
      <Controls:DataGridTemplateColumn.CellEditingTemplate> 
       <DataTemplate> 

        <ComboBox DisplayMemberPath="ShortName" 
           MinWidth="200" MinHeight="25" 
           SelectedItem="{Binding Path=Officer, Mode=TwoWay, ValidatesOnExceptions=True, NotifyOnValidationError=True}" 
           ItemsSource="{Binding Officers, Source={StaticResource ReferenceListRetriever}}" /> 

       </DataTemplate> 
      </Controls:DataGridTemplateColumn.CellEditingTemplate> 
     </Controls:DataGridTemplateColumn> 

Répondre

4

Dans un DataTemplate, le DataContext est lié à chaque élément de la liste correspondante; Puisque toutes les liaisons se réfèrent implicitement à DataContext, vous devez vous assurer que le chemin est valide, à partir de l'élément de données unique.

Dans votre scénario, pour l'indication de liaison au travail, vous devriez avoir une machine virtuelle en forme de cette façon:

public class MyVM { 
    public IEnumerable<MyItem> Items {get;} 
} 

public class MyItem { 
    public Foo Foo {get;} 
    public Officer Officer {get;set;} 
    public IEnumerable<Officer> Officers {get;} 
} 

Il peut sembler un surpuissant, mais dans certains scénarios chaque combo peut contenir en fait des choix différents pour chaque élément de données, basé sur une règle métier. Dans les cas plus simples MyItem peuvent simplement exposer une liste commune en provenance de la MyVM mère:

public class MyItem { 
    ... 
    public IEnumerable<Officer> Officers { 
    get { return _parent.AvailableOfficers; } 
    } 
} 

Si vous ne pouvez vraiment pas vivre avec elle et préfèrent garder la liste des agents disponibles dans la racine VM uniquement, vous pouvez utiliser un tour du côté Xaml:

public class MyVM { 
    public IEnumerable<MyItem> Items {get;} 
    public IEnumerable<Officer> Officers {get;} 
} 

public class MyItem { 
    public Foo Foo {get;} 
    public Officer Officer {get;set;} 
} 

Xaml:

<UserControl ...> 
    ... 
    <AnyFrameworkElementAtThisLevel Name="bridge" /> 
    ... 
    <Controls:WhateverGrid> 
    ... 
    <Controls:DataGridTemplateColumn ...> 
     <Controls:DataGridTemplateColumn.CellTemplate> 
      <DataTemplate> 
       ... 
      </DataTemplate> 
     </Controls:DataGridTemplateColumn.CellTemplate> 
     <Controls:DataGridTemplateColumn.CellEditingTemplate> 
      <DataTemplate> 
       <ComboBox DisplayMemberPath="ShortName" 
          SelectedItem="{Binding Path=Officer, Mode=TwoWay, ValidatesOnExceptions=True, NotifyOnValidationError=True}" 
          ItemsSource="{Binding DataContext.Officers, ElementName=bridge}" /> 

      </DataTemplate>