Как связать поле со списком Silverlight DataGrid itemSource для viewModel - PullRequest
3 голосов
/ 30 октября 2010

Мы используем Caliburn.Micro / Silverlight 4, и жизнь хороша.

Я пытаюсь привязать itemsSource комбинированного списка к viewModel, но это кажется невозможным, так как комбинированный список уже связан с dataItem его собственной строки. Логика, которая заполняет комбо, меняется вместе с другими данными на экране, поэтому я не могу использовать статический список, как я использовал.

Есть ли способ как-то привязать каталог к ​​viewModel ??? Я пробовал привязку элемента к элементу, но это никогда не работает в сетке.

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

1 Ответ

4 голосов
/ 30 октября 2010

В DataTemplate DataContext привязывается к каждому отдельному элементу соответствующего списка;поскольку все привязки неявно ссылаются на DataContext, необходимо убедиться, что путь допустим, , начиная с одного элемента данных .

В вашем сценарии для работы указанной привязки у вас должна быть виртуальная машина в форме:

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

Это может показаться излишним, но в некоторых сценариях каждая комбинация может фактически содержатьразличные варианты для каждого элемента данных, основанные на некоторых бизнес-правилах.В более простых случаях MyItem может просто предоставить общий список, исходящий от родительского MyVM:

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

Если вы действительно не можете с этим жить и предпочитаете сохранить список доступных сотрудников только в корневой виртуальной машине, вы можетеиспользуйте трюк с 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>
...