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

时间:2011-04-14 10:56:23

标签: c# wpf checkbox listbox selection

我正在使用带有复选框的列表框来选择其中的数据。源是一个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>

列表框正确显示复选框。当我选择一个或多个条目时,我无法检索关联的HostName。选择通过以下方式完成:

    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>

有任何帮助吗?我被困在那里几个小时没有线索..

2 个答案:

答案 0 :(得分:0)

我认为你回来了一个XElement,因为你首先将它们添加到MachinesList中。但为什么这会成为一个问题呢?您仍然可以从该XML片段中选择子elements并选择您的主机名。

答案 1 :(得分:0)

假设您要选择Host元素,您现在所拥有的内容应该正常工作,但是您没有提供足够的详细信息以及MessageBoxes以查看任何内容。通过在事件处理程序中设置断点很容易看到这一点,但如果您想在MessageBoxes中看到更多信息,则可以更具体地说明要显示的内容。

在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>