我们正在使用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>
答案 0 :(得分: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;}
}
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>