在新列表中只显示列表框中选定的项目

本文关键字:列表 项目 显示 新列表 | 更新日期: 2023-09-27 18:11:34

我对WPF和XAML比较陌生。

我在XAML中有一个ListBox Name="EmployeeTitles"(如下所示)。为了演示问题DataContext = employeesObservableCollection<Employee>

        <ListBox Name="EmployeeTitles"
            ItemsSource="{Binding}"
            SelectionMode="Extended">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <ToggleButton IsChecked="{Binding IsSelected, Mode=TwoWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBoxItem}}}">
                            <!--StackPanel will have more items-->
                            <StackPanel Orientation="Horizontal">
                                <TextBlock Text="{Binding Title}"/>
                            </StackPanel>                         
                        </ToggleButton>
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>

我的"Code Behind"类片段如下:

private string _title;
public string Title
{
    get { return _title; }
    set
    {
        _title = value;
        OnPropertyChanged();
    }
}
private bool _isSelected;
public bool IsSelected
{
    get
    {
        return _isSelected;
    }
    set
    {
        _isSelected = value;
        OnPropertyChanged();
    }
}

我想在另一个控件中显示选中的项。例如,有一个只显示选定项目的列表。我可以以某种方式在XAML中标记,我只想显示项目与IsChecked="True" ?我知道我可以有另一个ObservableCollection只存储选定的项目和更新它在"代码后面"每当属性IsSelected的变化,但这似乎是一个开销,我想应该有一种方法来做到这一点在XAML?

在新列表中只显示列表框中选定的项目

您可以将另一个列表框与原始列表框的选定项绑定。试试下面的代码:

<Grid>
    <StackPanel Orientation="Horizontal">
        <ListBox x:Name="Emp" ItemsSource="{Binding EmpCollection}" SelectionMode="Extended">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <ToggleButton IsChecked="{Binding IsSelected, Mode=TwoWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBoxItem}}}">
                            <!--StackPanel will have more items-->
                            <StackPanel Orientation="Horizontal">
                                <TextBlock Text="{Binding Title}"/>
                            </StackPanel>
                        </ToggleButton>
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
        <ListBox x:Name="SelectedEmp" ItemsSource="{Binding ElementName=Emp,Path=SelectedItems}" DisplayMemberPath="Title"/>
    </StackPanel>
</Grid>
public partial class Window2 : Window
{
    public Window2()
    {
        InitializeComponent();
        this.DataContext = new ViewModel();
    }
}

class ViewModel
{
    public ObservableCollection<Emp> EmpCollection { get; set; }
    public ViewModel()
    {
        EmpCollection = new ObservableCollection<Emp>();
        for (int i = 0; i < 10; i++)
        {
            EmpCollection.Add(new Emp() {Title = "Title"+i});
        }
    }
}
class Emp:INotifyPropertyChanged
{
    private string _title;
    public string Title
    {
        get { return _title; }
        set
        {
            _title = value;
            OnPropertyChanged();
        }
    }
    private bool _isSelected;
    public bool IsSelected
    {
        get
        {
            return _isSelected;
        }
        set
        {
            _isSelected = value;
            OnPropertyChanged();
        }
    }
    public event PropertyChangedEventHandler PropertyChanged;
    [NotifyPropertyChangedInvocator]
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}