3

我们正在使用 Caliburn.Micro/Silverlight 4,生活很好。

我正在尝试将组合框的 itemsSource 绑定到 viewModel,但这似乎不可能,因为组合框已经绑定到它自己的行的 dataItem。填充组合的逻辑会随着屏幕上的其他数据而变化,所以我不能像我一直使用的那样真正使用静态列表。

有没有办法以某种方式将目录绑定到视图模型???我已经尝试过元素到元素的绑定,但这似乎永远不会在网格中工作。

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

1 回答 1

4

在 DataTemplate 中,DataContext 绑定到相应列表的每一项;由于所有 Bindings 都隐式引用 DataContext,因此您必须确保路径有效,从单个数据项开始

在您的场景中,为了使指定的绑定起作用,您应该有一个这样形成的 VM:

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

如果您真的无法忍受它并且更愿意将可用的官员列表仅保留在根 VM 中,您可以使用 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;}
}

xml:

<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>
于 2010-10-30T16:24:31.810 回答