如何绑定到列表项

本文关键字:列表 绑定 何绑定 | 更新日期: 2023-09-27 18:17:08

我在一个页面上有一个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。

如何绑定到列表项

你试过吗?

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

应该可以了。给模板一个密钥,并将其作为StaticResource分配给ItemsPanelTemplate属性。

<mvvm:ViewObject.Resources>
    <fabricman:MyConverter x:Key="Converter" />
    <DataTemplate x:Key="FabricTierItem" DataType="{x:Type discovery:FabricTierMetadata}">
        <fabricman:FabricManInstanceItem Metadata="{Binding Converter={StaticResource Converter}}"/>
    </DataTemplate>
</mvvm:ViewObject.Resources>
<Grid>
    <TabControl TabStripPlacement="Bottom">
        <TabItem Header="Clouds">
            <ListBox ItemsPanelTemplate="{StaticResource FabricTierItem}" 
                     Background="Transparent" ItemsSource="{Binding AvailableClouds}" 
                     HorizontalContentAlignment="Stretch" />
        </TabItem>
    </TabControl>
</Grid>