Wpf CheckedListbox - 如何获取所选项目

use*_*448 8 c# wpf xaml

我使用以下代码在xaml中创建了一个CheckedListbox:

                    <ListBox Height="340" ItemsSource="{Binding Sections}" SelectedItem="{Binding SelectedSection}">
                    <ListBox.ItemTemplate>
                        <DataTemplate>
                            <CheckBox IsChecked="{Binding IsChecked}" Content="{Binding Path=Item}" />
                        </DataTemplate>
                    </ListBox.ItemTemplate>
                </ListBox>
Run Code Online (Sandbox Code Playgroud)

它绑定到这个集合:

public ObservableCollection<CheckedListItem<String>> Sections { get; set; }
private CheckedListItem<String> _selectedSection;
public CheckedListItem<String> SelectedSection
    {
        get { return _selectedSection; }
        set 
        {
            _selectedSection = value; 
            RaisePropertyChanged("SelectedSection"); 
        }
    }
Run Code Online (Sandbox Code Playgroud)

CheckedListItem类如下所示:

    public class CheckedListItem<T> : INotifyPropertyChanged
    {
    public event PropertyChangedEventHandler PropertyChanged;

    private bool isChecked;
    private T item;

    public CheckedListItem()
    { }

    public CheckedListItem(T item, bool isChecked = false)
    {
        this.item = item;
        this.isChecked = isChecked;
    }

    public T Item
    {
        get { return item; }
        set
        {
            item = value;
            if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("Item"));
        }
    }


    public bool IsChecked
    {
        get { return isChecked; }
        set
        {
            isChecked = value;
            if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("IsChecked"));
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我试图在_selectedSection =值中设置断点; 代码的一部分,但是当我在CheckedListBox中选择/取消选择一个项时,它永远不会被触发.

我的问题是,每次选择/取消选中时,我如何获得所选项目?

谢谢

123*_*9 0 9

改变你XAML

<ListBox Height="340" ItemsSource="{Binding Sections}" SelectedItem="{Binding SelectedSection}">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <ListBoxItem IsSelected="{Binding IsChecked}">
                <CheckBox IsChecked="{Binding IsChecked}" Content="{Binding Path=Item}" />
            </ListBoxItem>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>
Run Code Online (Sandbox Code Playgroud)

您可能正在点击textblock控件内部的实际控件checkbox,square而不会触发selectionchangeda listbox.如果你试图在矩形的边界外面点击,whitespace那么它会触发.

如果你只想要checkboxas as datatemplate,那将是更多的工作,因为你想listboxitem根据checkbox IsChecked属性选择/取消选择' .所以只需把它包在里面ListBoxItem就可以了.


hon*_*989 6

我的解决方案(基于上面的Suplanuslll解决方案):

<ListBox ItemsSource="{Binding Checkboxes}" SelectionMode="Multiple">
    <ListBox.ItemContainerStyle>
        <Style TargetType="ListBoxItem">
            <Setter Property="IsSelected" Value="{Binding Checked, Mode=TwoWay}" />
        </Style>
    </ListBox.ItemContainerStyle>
    <ListBox.ItemTemplate>
        <DataTemplate>
            <CheckBox IsChecked="{Binding Checked, Mode=TwoWay}" Content="{Binding Label}"/>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>
Run Code Online (Sandbox Code Playgroud)

我设置了 ListBoxItem IsSelected 属性 througt 样式(因为标准lll 的方式不能很好地工作)!在这种情况下,当 CheckBox 被选中时 ListBoxItem 被选中,反之亦然。在这种情况下,SelectionMode 也能很好地工作。您可以在 Single SelectionMode 中添加 SelectedItem(或类似属性)

<!-- xaml -->
SelectedItem="{Binding SelectedCheckbox}" SelectionMode="Single"
// cs
public CheckboxData SelectedCheckbox { get; set; }
Run Code Online (Sandbox Code Playgroud)

或者甚至更好,直接在后台代码(例如您的 ViewModel)中使用 ItemsSource(在这种情况下为 Checkboxes 集合)。

后面的代码(例如):

public partial class MainWindow : Window
{
    public class CheckboxData
    {
        public int Id { get; set; }
        public string Label { get; set; }
        public bool Checked { get; set; }
    }

    public MainWindow()
    {
        DataContext = this;
        for (int i = 0; i < 50; i++)
            Checkboxes.Add(new CheckboxData { Id = i, Label = $"Checkbox {i}" });
    }

    public IList<CheckboxData> Checkboxes { get; set; } = new List<CheckboxData>();
}
Run Code Online (Sandbox Code Playgroud)

注意:
如果您想从代码后面更改 Checkboxes 集合(或选定项)(并反映 UI 中的更改),您必须实现INotifyPropertyChanged并在集合(或选定项)发生更改时(字面意思是重新创建对象时)发出通知.