Binding IsSelected Method in the ListView Control in WinRT

September 18, 2014

Basically, it’s not possible. However, this is the best (and only that works) workaround that I found.

Subclass the Listview

I tried everything. Absolutely everything.

I tried straightforward binding - that doesn’t work for IsSelected. I tried using WinRT Xaml Toolkit - didn’t work. I tried using Setters - they don’t work for WinRT.

Finally, I came across this solution; here’s the listview subclass (stolen directly from here: http://stackoverflow.com/questions/15994021/listviewitem-isselected-binding-works-for-wpf-but-not-for-winrt):


    public class ListViewEx : ListView
    {
        protected override void PrepareContainerForItemOverride(Windows.UI.Xaml.DependencyObject element, object item)
        {
            base.PrepareContainerForItemOverride(element, item);
            
            ListViewItem listItem = element as ListViewItem;
            Binding binding = new Binding();
            binding.Mode = BindingMode.TwoWay;
            binding.Source = item;
            binding.Path = new PropertyPath("IsSelected");
            listItem.SetBinding(ListViewItem.IsSelectedProperty, binding);
        }
    }

Obviously this does restrict the IsSelected property name. My class looks something like this:


    public class Person
    {
        public string Name { get; set; }}

I didn’t want to add an IsSelected property to this; because it doesn’t directly relate to the entity. My solution was to wrap this inside a class such as this:



    public class SelectableItem : INotifyPropertyChanged
    {
        private T \_item;
        public T Item 
        {
            get { return \_item; }
            set
            {
                \_item = value;
                RaisePropertyChanged();
            }
        }

        private bool \_isSelected;
        public bool IsSelected
        {
            get { return \_isSelected; }
            set
            {
                \_isSelected = value;                
                RaisePropertyChanged();
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
        protected void RaisePropertyChanged([CallerMemberName] string name = "")
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(name));
            }
        }
}

And build it like this:


                List population = GetPeople();
                SelectablePeople = new ObservableCollection\>(population
                    .Select(n => new SelectableItem() { Item = n, IsSelected = false }).ToList());

So, finally, bind the collection to the new subclassed listview like this:



        



Profile picture

A blog about one man's journey through code… and some pictures of the Peak District
Twitter

© Paul Michaels 2022