If you want to filter by Selected, bind the ICollectionView of Selected=false
data to the ListBox on the left, and bind the ICollectionView of Selected=true
data to the ListBox on the right, you could try to use the following method.
UserControl1.xaml:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<ScrollViewer Grid.Column="0" VerticalScrollBarVisibility="Auto">
<ListBox ItemsSource="{Binding Source}">
<ListBox.ItemTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding Selected, Mode=TwoWay}"
Content="{Binding DisplayString}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</ScrollViewer>
<StackPanel Grid.Column="1" VerticalAlignment="Center">
<Button Content="<" />
<Button Content="<<" />
<Button Content=">" />
<Button Content=">>" />
</StackPanel>
<ScrollViewer Grid.Column="2" VerticalScrollBarVisibility="Auto">
<ListBox ItemsSource="{Binding Destination}" >
<ListBox.ItemTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding Selected, Mode=TwoWay}"
Content="{Binding DisplayString}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</ScrollViewer>
</Grid>
UserControl1.xaml.cs:
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows.Controls;
using System.Windows.Data;
namespace UserControl1
{
public partial class UserControl1 : UserControl
{
SampleDualListViewModel vm;
public UserControl1()
{
InitializeComponent();
vm=new SampleDualListViewModel();
this.DataContext=vm;
}
}
public class SampleDualListViewModel
{
SampleData sampleData;
public ICollectionView Destination { get; set; }
public ICollectionView Source { get; set; }
public CollectionViewSource CvsSelected{ get;set;}
public CollectionViewSource CvsNotSelected{ get;set;}
private ObservableCollection<SampleData> data;
public ObservableCollection<SampleData> Data
{
get { return data; }
set
{
data = value;
}
}
public IEnumerable<SampleData> Items { get { return data; } }
public SampleDualListViewModel()
{
data = new ObservableCollection<SampleData>();
for (int i = 0; i< 20; i++)
{
sampleData = new SampleData(){ DisplayString= $"Line {i}", Selected= i % 2 == 0 };
data.Add(sampleData);
}
CvsSelected = new CollectionViewSource();
CvsSelected.Source=Data;
CvsSelected.Filter += (s, e) =>
{
SampleData sd=e.Item as SampleData;
e.Accepted = sd.Selected;
};
Destination = CvsSelected.View;
Destination.Refresh();
CvsNotSelected = new CollectionViewSource();
CvsNotSelected.Source = Data;
CvsNotSelected.Filter += (s, e) =>
{
SampleData sd = e.Item as SampleData;
e.Accepted = !sd.Selected;
};
Source = CvsNotSelected.View;
Source.Refresh();
}
}
public class SampleData : INotifyPropertyChanged
{
public SampleData() { }
public SampleData(string s)
{
DisplayString = s;
}
private string displayString;
public string DisplayString
{
get { return displayString; }
set
{
displayString = value;
OnPropertyChanged("DisplayString");
}
}
private bool selected;
public bool Selected
{
get { return selected; }
set
{
selected = value;
OnPropertyChanged("Selected");
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string name = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
}
}
MainWindow.xaml:(Test)
<Window x:Class="Test.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Test"
xmlns:dualListUserControls="clr-namespace:UserControls.DualListUserControls;assembly=UserControls"
xmlns:uc="clr-namespace:UserControl1;assembly=UserControl1"
mc:Ignorable="d"
Title="MainWindow" Height="407" Width="300">
<StackPanel >
<uc:UserControl1 Height="300" />
</StackPanel>
</Window>
The result:
If the response is helpful, please click "Accept Answer" and upvote it.
Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.