2011-04-14 154 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並選擇您的主機名。