如何使用 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
都是关于约定的。如果将 ComboBox
的 Name
设置为 "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}"/>
这是我使用 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
都是关于约定的。如果将 ComboBox
的 Name
设置为 "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}"/>