具有复选框的C#WPF列表框-选择显示

| 我正在使用带有复选框的列表框来选择其中的数据。源是一个XML文件,例如:
<Hosts>
  <Host Location=\"a\">
    <IP>1.1.1.1</IP>
    <HostName>host1</HostName>
  </Host>
  <Host Location=\"b\">
    <IP>2.2.2.2</IP>
    <HostName>host2</HostName>>
  </Host>
</Hosts>
列表框正确显示了复选框。选择一个或多个条目时,无法获取关联的主机名。选择是通过:
    private void CheckBox_Checked(object sender, RoutedEventArgs e)
    {
        var cb = sender as CheckBox;
        var item = cb.DataContext;
// a message box here shows that I have the good content (host1, host2) in item
        ListBoxItem listBoxItem = (ListBoxItem)this.MachinesList.ItemContainerGenerator.ContainerFromItem(item);
        listBoxItem.IsSelected = true;
        MessageBox.Show(listBoxItem.ToString());
    }
我正在使用一个按钮来显示内容:
private void button1_Click(object sender, RoutedEventArgs e)
{
    foreach (Object selecteditem in MachinesList.SelectedItems)
    {
        MessageBox.Show(selecteditem.ToString());
    }
}
但是消息框正在打印:System.XML.XmlElement 恐怕该选择将应用于整个XML数据,而不是特定的节点。即:
ListBoxItem listBoxItem = (ListBoxItem)this.MachinesList.ItemContainerGenerator.ContainerFromItem(item);
不选择节点,而是选择完整的XML元素。 列表框通过以下方式完成:
<!-- MACHINES LIST -->
        <!-- Grouping option for machines list -->
        <CollectionViewSource x:Key=\"cvs\" Source=\"{Binding Source={StaticResource HostsData}}\">
            <CollectionViewSource.GroupDescriptions>
                <PropertyGroupDescription PropertyName=\"@Location\" />
            </CollectionViewSource.GroupDescriptions>
        </CollectionViewSource>
        <!-- Display option for groups in machines list -->
        <DataTemplate x:Key=\"categoryTemplate\">
            <TextBlock Text=\"{Binding Path=Name}\"  FontWeight=\"Bold\" Background=\"Gold\" Margin=\"0,5,0,0\"/>
        </DataTemplate>
        <!-- Display option for machines in machines list -->
        <DataTemplate x:Key=\"MachinesTemplate\">
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition/>
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition/> <ColumnDefinition/>
                </Grid.ColumnDefinitions>
                <CheckBox Content=\"{Binding XPath=HostName}\" Checked=\"CheckBox_Checked\"   Grid.Row=\"0\" Grid.Column=\"0\"    Margin=\"1\"/>
            </Grid>
        </DataTemplate>

   <ListBox Name=\"MachinesList\"
             Grid.Row=\"0\"    Grid.Column=\"0\"    Grid.RowSpan=\"2\"    TextBlock.FontSize=\"9\" Margin=\"2\"
             ItemsSource=\"{Binding Source={StaticResource cvs}}\"
             ItemTemplate=\"{StaticResource MachinesTemplate}\"
             SelectionMode=\"Multiple\">
        <ListBox.GroupStyle>
            <GroupStyle HeaderTemplate=\"{StaticResource categoryTemplate}\" />
        </ListBox.GroupStyle>
    </ListBox>
有什么帮助吗?我在那儿呆了几个小时,一无所知。     
已邀请:
假设您要选择Host元素,那么您现在拥有的应该可以正常工作,但是您没有在MessageBox中提供足够的详细信息以查看任何内容。只需在事件处理程序中设置一个断点就可以很容易地看到这一点,但是如果您想在MessageBox中看到更多内容,则可以更具体地显示内容。 在Checked处理程序中使用它代替您应该看到所选项目是\“ Host \”元素:
MessageBox.Show((listBoxItem.Content as XmlElement).Name);
枚举所选项目时,您可以类似地检查该元素属于所需的详细程度:
foreach (var selecteditem in MachinesList.SelectedItems.OfType<XmlElement>())
{
    MessageBox.Show(selecteditem.InnerXml);
}
在开始将其实际使用之前,您还需要更改处理CheckBox和ListBoxItem同步的方式。至少您还需要在CheckBox上有一个Unchecked处理程序,但是您可以通过取消事件处理程序并使用数据绑定来简化操作:
<DataTemplate x:Key=\"MachinesTemplate\">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <CheckBox Content=\"{Binding XPath=HostName}\" Margin=\"1\"
                  IsChecked=\"{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBoxItem}}, Path=IsSelected}\"/>
    </Grid>
</DataTemplate>
    
我想您将获得XElement,因为您首先将它们添加到了MachinesList中。但是,为什么会出现问题呢?您仍然可以从该XML片段中选择子元素,然后选择您的主机名。     

要回复问题请先登录注册