get all selected items from wpf checkbox list give

2019-09-16 04:31发布

问题:

I have ListBox with checked box as following, and it binding its data from SQL server database. I want to get selected items value When I run this but I got this error:

Unable to cast object of type 'System.Data.DataRowView' to type 'System.Windows.Controls.CheckBox'.

This is code:

<Window.Resources>
    <DataTemplate x:Key="NameColumnTemplate">
        <CheckBox Height="20" FontFamily="Arial" FontSize="14" Content="{Binding Path=PermissionDescription}" Tag="{Binding PermissionID}" HorizontalAlignment="Stretch" VerticalAlignment="Center" />
    </DataTemplate>
</Window.Resources>

<Grid>
    <ListBox HorizontalAlignment="Stretch" Margin="12,12,136,21" Name="lstEmployees" 
         VerticalAlignment="Stretch" ItemsSource="{Binding Tables[0]}"  
         ItemTemplate="{StaticResource NameColumnTemplate}" 
         ScrollViewer.VerticalScrollBarVisibility="Auto" removed="{x:Null}"
         BorderBrush="#FFAD7F30"  
         SelectionChanged="lst_SelectionChanged" CheckBox.Click="lst_SelectionChanged"/>

    <Button Content="listbox" Height="23" HorizontalAlignment="Left" Margin="214,207,0,0" Name="btnShowSelectedItems" VerticalAlignment="Top" Width="75" Click="btnShowSelectedItems_Click" />
</Grid>

public Window2()
{
    InitializeComponent();
    // bind data 
    lstEmployees.DataContext = SelJobsCat();
}

private void btnShowSelectedItems_Click(object sender, RoutedEventArgs e)
{
    foreach (CheckBox item in lstEmployees.Items)
    {
        if (item.IsChecked == true)
        {
            System.Windows.MessageBox.Show((item.Content + " is checked."));
        }
    }
}

private void lst_SelectionChanged(object sender, RoutedEventArgs e)
{
    if (e.OriginalSource is CheckBox)
    {
        lstEmployees.SelectedItem = e.OriginalSource;
    }

    if (lstEmployees.SelectedItem == null) return;

    Console.WriteLine(lstEmployees.SelectedIndex);
    Console.WriteLine(((CheckBox)lstEmployees.SelectedItem).IsChecked);
 }

Where is my error please, Thanks.

回答1:

ListBox.Items is set to a DataTable in your XAML (ItemsSource="{Binding Tables[0]}"), so looping through ListBox.Items is looping through DataRowView objects, not the CheckBox objects

Your best bet is to add a bool column to your DataContext (the DataTable) so you can bind CheckBox.IsChecked to it.

You could also use the ItemContainerGenerator to generate the XAML item generated for the data item, however this may not be accurate because ListBoxes are virtualized by default, which means if you don't bind a value to the DataContext, it won't necessarily be kept.

To work with WPF the right way, you really should add a bool value to the DataContext