2011-04-14 214 views
1

我正在使用带有复选框的列表框来选择其中的数据。源代码是一个XML文件,如下所示:带有复选框的C#WPF列表框 - 选择显示

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

任何帮助:

列表框与做了什么?我被困在那里几个小时没有线索..

回答

0

假设你想要选择主机元素,你现在应该正确地工作,但你没有提供足够的细节与你的MessageBoxes看到任何东西。通过在事件处理程序中设置断点很容易看到这一点,但如果希望在MessageBox中看到更多内容,则可以更具体地展示要显示的内容。

在经过处理程序使用此相反,你应该看到,所选择的项目是“主机”元素:

MessageBox.Show((listBoxItem.Content as XmlElement).Name); 

当枚举所选的项目,你同样可以检查它是下降到什么水平,这元素细节你需要:

foreach (var selecteditem in MachinesList.SelectedItems.OfType<XmlElement>()) 
{ 
    MessageBox.Show(selecteditem.InnerXml); 
} 

你开始使用这是真的在你还需要改变你是如何处理的复选框,并ListBoxItem中的同步。您至少还需要对复选框的未选中处理程序,但你可以摆脱事件处理程序,并使用数据绑定,而不是让它变得简单许多:

<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> 
+0

你好约翰。非常感谢你。这工作完美。你发布的绑定例子的确比我所做的更清晰。我一直在寻找很多时间,如何正确地做这个listbox/checkbox,没有一个最终答案。 – 2011-04-14 18:22:25

0

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