如何使用 Caliburn.Micro 绑定 ItemsControl 中的 ComboBox?

How to Bind ComboBox Inside ItemsControl with Caliburn.Micro?

这是我使用 WPF 和 Caliburn.Micro 的项目。在我看来,我有一个绑定到 BindableCollection 的 ItemsControl,在对应的 ViewModel 中,记录 class (MemberVotes)。 class 只有两个字段:MemberName 和 Vote。 ViewModel 还有第二个字符串类型的 BindableCollection (VoteOptions)。 ViewModel 中的 Handle 方法将数据加载到两个 BindableCollections 中。 MemberVotes 是从数据库加载的,VoteOptions 是通过代码添加新的字符串集合来加载的。

我可以毫无问题地在文本框中显示成员姓名和投票,但我无法让 ComboBox 绑定投票选项集合。没有错误消息。 ComboBoxes 只是空的。

如何将 ComboBoxes 绑定到 VoteOptions,然后将每个 ComboBox 的所选项目设置为 Vote?

如有任何帮助,我们将不胜感激。

视图 (MemberVoteView):

<ItemsControl x:Name="MemberVotes">
    <ItemsControl.ItemTemplate>
        <DataTemplate>

        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="4*" />
                <ColumnDefinition Width="*" />
                <ColumnDefinition Width="*" />
            </Grid.ColumnDefinitions>

            <TextBox Text="{Binding MemberName}" Grid.Column="0" IsReadOnly="True" />

            <ComboBox Grid.Column="1" ItemsSource="{Binding RelativeSource={RelativeSource AncestorType=ItemsControl}, Path=DataContext.MemberVoteView.VoteOptions}" />

            <TextBox Grid.Column="2" Text="{Binding Vote}" />
        </Grid>

        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

ViewModel (MemberVoteViewModel):

    public BindableCollection<MemberVoteModel> MemberVotes { get; set; }

    public BindableCollection<string> VoteOptions { get; set; }

    public void Handle()
    {
        MemberVotes = new BindableCollection<MemberVoteModel>();
        MemberVotes .AddRange(GetVotes());

        VoteOptions = new BindableCollection<string>();
        VoteOptions.AddRange( new string[] { "Y", "N", "NV", "E", "O"} );
    }

希望我正确理解了你的问题。您的问题在于以下行。

<ComboBox Grid.Column="1" ItemsSource="{Binding RelativeSource={RelativeSource AncestorType=ItemsControl}, Path=DataContext.MemberVoteView.VoteOptions}" />

ItemsControl 的 DataContext 是您的 ViewModel。它没有名为 MemberVoteView 的 属性。你需要的是

<ComboBox Grid.Column="1" ItemsSource="{Binding RelativeSource={RelativeSource AncestorType=ItemsControl}, Path=DataContext.VoteOptions}" />

要将SelectedItem设置为投票,需要将ComboBox的SelectedItem属性绑定到MemberVotes.Vote。

例如,

<ComboBox Grid.Column="1" ItemsSource="{Binding RelativeSource={RelativeSource AncestorType=ItemsControl}, Path=DataContext.VoteOptions}" SelectedItem="{Binding Vote}" />

Caliburn.Micro 都是关于约定的。如果将 ComboBoxName 设置为 "VoteOptions" 并将 VoteOptions 属性 移动到 MemberVoteModel class 并添加a SelectedVoteOption 属性(使用这个确切的名称)到这个 class,以下应该有效:

<DataTemplate>
    <Grid cal:Bind.Model="{Binding}">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="4*" />
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>

        <TextBox x:Name="MemberName" Grid.Column="0" IsReadOnly="True" />

        <ComboBox x:Name="VoteOptions" />

        <TextBox Grid.Column="2" x:Name="SelectedVoteOption" />
    </Grid>
</DataTemplate>

您还应该考虑将 MemberVoteModel 重命名为 MemberVoteViewModel(您必须想出一个不同的名称或重命名您当前的视图模型)并定义一个单独的视图。这将是 Caliburn.Micro 的设置方式。

如果您决定在当前视图模型 class 中保留 VoteOptions 属性,您可以使用像这样的内置机制绑定到它:

<ComboBox ItemsSource="{Binding RelativeSource={RelativeSource AncestorType=ItemsControl}, Path=DataContext.VoteOptions}"
          SelectedItem="{Binding SelectedVoteOption}"/>