I am having one problem to bind SelectedItems of ListView control, in order to solve it i have extended ListView control, ListViewExtended
to expose SelectedItemsList using the reference from this post but two way binding is not working to get the SelectedItems in the model.
Kindly helps to point out the issue in this demo source.
Custom Control:
public sealed class ListViewExtended : ListView
{
public ListViewExtended()
{
this.SelectionChanged += ListViewExtended_SelectionChanged;
}
void ListViewExtended_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
this.SelectedItemsList = this.SelectedItems;
}
#region SelectedItemsList
public IEnumerable SelectedItemsList
{
get { return (IEnumerable)GetValue(SelectedItemsListProperty); }
set { SetValue(SelectedItemsListProperty, value); }
}
public static readonly DependencyProperty SelectedItemsListProperty =
DependencyProperty.Register("SelectedItemsList",
typeof(IEnumerable),
typeof(ListViewExtended),
new FrameworkPropertyMetadata(null));
#endregion
}
Model:
public class Member
{
public string Name { get; set; }
public int Age { get; set; }
}
public class Family : BindableBase
{
private string _name;
public string Name
{
get { return _name; }
set { _name = value; OnPropertyChanged("Name"); }
}
private IList<Member> _selectedMembers;
public IList<Member> SelectedMembers
{
get { return _selectedMembers; }
set { _selectedMembers = value; OnPropertyChanged("SelectedMembers"); }
}
public override string ToString()
{
return Name;
}
}
ViewModel:
public class ListViewSelectedItemsExtendedViewModel : BindableBase
{
Dictionary<string, IEnumerable> _repository = new Dictionary<string, IEnumerable>();
public ListViewSelectedItemsExtendedViewModel()
{
var families = new List<Family>();
families.Add(new Family() { Name = "family 1" });
families.Add(new Family() { Name = "family 2" });
Families = families;
var items = new List<Member>();
items.Add(new Member() { Name = "John", Age = 30 });
items.Add(new Member() { Name = "Chapel", Age = 50 });
items.Add(new Member() { Name = "Max", Age = 46 });
_repository.Add(families[0].Name, items);
items = new List<Member>();
items.Add(new Member() { Name = "Warner", Age = 28 });
items.Add(new Member() { Name = "Peter", Age = 36 });
items.Add(new Member() { Name = "Tom", Age = 5 });
_repository.Add(families[1].Name, items);
}
private IList<Family> _families;
public IList<Family> Families
{
get { return _families; }
set { _families = value; OnPropertyChanged("Families"); }
}
private Family _selectedFamily;
public Family SelectedFamily
{
get { return _selectedFamily; }
set { _selectedFamily = value; OnPropertyChanged("SelectedFamily"); }
}
private ICommand _familySelectionChangedCommand;
public ICommand FamilySelectionChangedCommand
{
get
{
return _familySelectionChangedCommand ?? (_familySelectionChangedCommand = new DelegateCommand(
() =>
{
Members = (IList<Member>)_repository[SelectedFamily.Name];
}
));
}
}
}
XAML:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="3*" />
</Grid.ColumnDefinitions>
<ListBox ItemsSource="{Binding Families}" SelectedItem="{Binding SelectedFamily}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<i:InvokeCommandAction Command="{Binding FamilySelectionChangedCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</ListBox>
<Grid Grid.Column="1">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<fsx:ListViewExtended Margin="10" Grid.Row="0"
ItemsSource="{Binding Members}"
SelectedItemsList="{Binding SelectedFamily.SelectedMembers, Mode=TwoWay}">
<ListView.View>
<GridView>
<GridViewColumn Header="Include">
<GridViewColumn.CellTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding Path=IsSelected,
RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListViewItem}}}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Name" Width="120" DisplayMemberBinding="{Binding Name}" />
<GridViewColumn Header="Age" Width="50" DisplayMemberBinding="{Binding Age}" />
</GridView>
</ListView.View>
<!--<i:Interaction.Behaviors>
<fsx:ListViewMultiSelectionBehavior
SelectedItems="{Binding SelectedFamily.SelectedMembers}" />
</i:Interaction.Behaviors>-->
</fsx:ListViewExtended>
<ListView Margin="10" Grid.Row="1"
ItemsSource="{Binding SelectedFamily.SelectedMembers}">
<ListView.View>
<GridView>
<GridViewColumn Header="Name" Width="120" DisplayMemberBinding="{Binding Name}" />
<GridViewColumn Header="Age" Width="50" DisplayMemberBinding="{Binding Age}" />
</GridView>
</ListView.View>
</ListView>
</Grid>
</Grid>
Apart from above implementation, i have also tried using the approach given in this post but no luck to get 100% results.