你如何绑定到列表项?

时间:2013-06-05 14:51:02

标签: c# wpf mvvm

我在页面上有一个ListBox,它使用控件的Resource部分中定义的以下数据模板。

<mvvm:ViewObject.Resources>
    <DataTemplate DataType="{x:Type discovery:FabricTierMetadata}">
        <fabricman:FabricManInstanceItem Metadata="{Binding}"/>
    </DataTemplate>
</mvvm:ViewObject.Resources>

意味着编写的是绑定当前列表项,但正在发生的是Metadata={Binding}绑定到控件的视图模型(而不是列表中的项目) )。如何编写它以使其与列表项而不是当前视图模型相关联?

<mvvm:ViewObject.Resources>
    <fabricman:MyConverter x:Key="Converter" />
        <DataTemplate DataType="{x:Type discovery:FabricTierMetadata}">
            <fabricman:FabricManInstanceItem Metadata="{Binding Converter={StaticResource Converter}}"/>
        </DataTemplate>
</mvvm:ViewObject.Resources>

<Grid>
    <TabControl TabStripPlacement="Bottom">
        <TabItem Header="Clouds">
            <ListBox Background="Transparent" ItemsSource="{Binding AvailableClouds}" HorizontalContentAlignment="Stretch" />
        </TabItem>
    </TabControl>
</Grid>

我添加了一个转换器用于调试目的(所以我可以看到正在发送的内容)。

背景源代码:

internal class FabricServiceManagerVM : ViewModelBase<FabricServiceManagerVM>
{
    public ViewModelCollection<FabricTierMetadata> AvailableClouds { get; private set; }

    public FabricServiceManagerVM()
    {
        this.AvailableClouds = new ViewModelCollection<FabricTierMetadata>();
        FabricServicingModel.ServiceManagerSetChanged += FabricServicingModel_ServiceManagerSetChanged;
    }

    void FabricServicingModel_ServiceManagerSetChanged(object sender, Model.Events.FabricServicingEndpointsChangedEventArgs args)
    {
        ServiceDiscoveryMetadata metadata = args.Metadatas.First();
        this.AvailableClouds.Add(new FabricTierMetadata(metadata.Name, metadata.Address)); 
    }
}

ViewModelCollection<T>基本上是一个加强的ObservableCollection

ListBox在我的AvailableClouds集合中显示正确数量的项目,这是正确的....但是当它应用DataTemplate时它发送了错误的项目。应该发送FabricTierMetadata的实例,而是通过视图模型发送。

更新

当我这样做时:

            <ListBox Background="Transparent" 
                     ItemsSource="{Binding AvailableClouds}" HorizontalContentAlignment="Stretch" >
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <Label Content="{Binding Name}" />
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>

它显示Name属性正常吗?然而,当我单独说{Binding}时,我就得到了VM。

2 个答案:

答案 0 :(得分:1)

你试过这个吗?

<DataTemplate DataType="{x:Type discovery:FabricTierMetadata}">
    <fabricman:FabricManInstanceItem Metadata="{Binding RelativeSource={RelativeSource AncestorType=ListBoxItem}}"/>
</DataTemplate>

答案 1 :(得分:0)

这应该这样做。为模板指定一个密钥,并将其指定为StaticResource属性{。}}。

ItemsPanelTemplate