what is the easiest way to bind selected state of listview's item to model's boolean property?
I'm not sure if this is the most easiest way, but for me I think it is the easiest way to bind SelectorItem.IsSelected property of ListViewItem
to your Selected
property in model. Only the problem is, we all know each item of ListView
is an instance of ListViewItem
, but when we use DataTemplate
to build the item structure for ListViewItem
, ListViewItem
s are not available in design-time. So my idea is to bind this property in code behind, just for example here:
<ListView x:Name="myListView" SelectionMode="Multiple" Loaded="myListView_Loaded" ItemsSource="{x:Bind Collection}">
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
code behind:
private ObservableCollection<Model> Collection = new ObservableCollection<Model>();
protected override void OnNavigatedTo(NavigationEventArgs e)
{
for (int i = 0; i < 100; i++)
{
Collection.Add(new Model { Name = "Name " + i });
}
}
private void myListView_Loaded(object sender, RoutedEventArgs e)
{
IEnumerable<ListViewItem> lvItems = FindVisualChildren<ListViewItem>(myListView);
if (lvItems != null)
{
foreach (ListViewItem lvitem in lvItems)
{
Model model = lvitem.Content as Model;
Binding b = new Binding
{
Source = model,
Path = new PropertyPath("Selected"),
Mode = BindingMode.TwoWay,
};
BindingOperations.SetBinding(lvitem, ListViewItem.IsSelectedProperty, b);
}
}
}
private static IEnumerable<T> FindVisualChildren<T>(DependencyObject depObj) where T : DependencyObject
{
if (depObj != null)
{
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
{
DependencyObject child = VisualTreeHelper.GetChild(depObj, i);
if (child != null && child is T)
{
yield return (T)child;
}
foreach (T childOfChild in FindVisualChildren<T>(child))
{
yield return childOfChild;
}
}
}
}
public class Model : INotifyPropertyChanged
{
public string Name { get; set; }
private bool _Selected;
public bool Selected
{
get { return _Selected; }
set
{
if (value != _Selected)
{
_Selected = value;
OnPropertyChanged();
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged([CallerMemberName]string propertyName = "")
{
if (this.PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}