Tree list with check boxes or ListBox with multiple selections within an ArcGIS PRO SDK pane

1945
5
01-17-2021 08:04 PM
FredericPoliart_EsriAU
Occasional Contributor II

Using ArcGIS Pro SDK 2.6, I am trying to create a ListBox where the user could select more than 1 item (holding shift / Ctrl key + click) 

I can create the listbox and handle the {ItemSource Binding} (for updating the list) and the {SelectedItem Binding} for handling the case of having one item clicked on, using RelayCommand().  

How do I configure the Pane ListBox item to allow for multi-line selection?

thank you 


ex ref: https://github.com/Esri/arcgis-pro-sdk-community-samples/blob/master/Framework/DockpaneSimple/Dockpa... 

0 Kudos
5 Replies
by Anonymous User
Not applicable

Hi @FredericPoliart_EsriAU ,

To enable multiple selections the shift/control modifiers, we just need to set SelectionMode="Extended" in the properties of the ListBox control in the associated XAML file. 

See Microsoft reference: https://docs.microsoft.com/en-us/dotnet/api/system.windows.controls.listbox?view=net-5.0#remarks

 

Cheers,
James

FredericPoliart_EsriAU
Occasional Contributor II

thank you @Anonymous User   
Now next question : How do I get the list of selected items in my ICommand RelayCommand() function?
Is there a special {binding} required?  (ex:  Binding SelectedItem array?)

 

 

Severity Code Description Project File Line Suppression State
Error XDG0013 The property "SelectedItems" does not have an accessible setter. 

0 Kudos
by Anonymous User
Not applicable

Hi @FredericPoliart_EsriAU ,

You can bind the UI with isselected property in xaml

 

 

 

<ListBox ItemsSource="{Binding Items}" SelectionMode="Extended">
    <ListBox.ItemContainerStyle>
        <Style TargetType="ListBoxItem">
            <Setter Property="IsSelected" Value="{Binding IsSelected}" />
        </Style>
    </ListBox.ItemContainerStyle>
</ListBox>

 

 

 

 

So as in above example, in your model , there should be property call IsSelected as boolean type.

 

 

 

private bool _isSelected;
public bool IsSelected
{
    get { return _isSelected; }
    set
    {
        _isSelected = value;
        this.NotifyPropertyChanged();
    }
}

 

 

 

 

And from you relay command, you can access selected item by 

 

 

 

Items.Where(i => i.IsSelected);

 

 

 

 

There is no SelectedItems property in listbox control but you can extend it to enable it.

Below is the custom listbox control class example, you can bind with IList collection type. (any object list you can use)

But I would recommend you to use isselected property approach because It is more straight forward.

 

 

 

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;

namespace ThanExtendControlLibrary.ExtendedControls
{
    public class CustomListBox : ListBox
    {
        public CustomListBox()
        {

            this.SelectionChanged += CustomListbox_SelectionChanged;            
        }

        private void CustomListbox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            this.SelectedItemsList = this.SelectedItems;
        }
        #region SelectedItemsList

        public IList SelectedItemsList
        {
            get { return (IList)GetValue(SelectedItemsListProperty); }
            set { SetValue(SelectedItemsListProperty, value); }
        }
       

        public static readonly DependencyProperty SelectedItemsListProperty =
                DependencyProperty.Register("SelectedItemsList", typeof(IList), typeof(CustomListBox), new PropertyMetadata(null));
       
        #endregion
    }
}

 

 

As in above extended control you can use it from your dockpane with

Add xmlns:local="clr-namespace: ThanExtendControlLibrary.ExtendedControls;assembly=[your assemblyname]:

 

 

<local:CustomListBox  ItemsSource="{Binding Items}" SelectionMode="Extended" 
 SelectedItemsList="{Binding Path=SelectedList, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
   
</local:CustomListBox>

<!-- Note: Declare SelectedList as IList in the model -->

 

 

 

0 Kudos
by Anonymous User
Not applicable

Hi @FredericPoliart_EsriAU ,

That error you're seeing XDG0013 The property "SelectedItems" does not have an accessible setter.  is a result of the fact that unlike the SelectedItem property, the SelectedItems property is read-only. 

The simplest approach I can I think of would be to handle the SelectionChanged event of the ListBox in the codebehind to execute a command in the view model, and pass the selected items from the event handler to the command. 

Using the DockpaneSimple project as an example, this would involve the following changes- 

BookmarkDockpaneViewModel.cs

// added to #region Private Properties
private ICommand _retrieveSelectedBookmarksCommand;

// added to #region Public Properties
public ICommand RetrieveSelectedBookmarksCommand => _retrieveSelectedBookmarksCommand;

// addded to BookmarkDockpaneViewModel() constructor 
_retrieveSelectedBookmarksCommand = new RelayCommand((selectedBookmarks) => RetrieveSelectedBookmarks(selectedBookmarks), () => true);

//added to #region Private Helpers
private void RetrieveSelectedBookmarks(object param)
{
	System.Collections.IList selectedItems = (System.Collections.IList)param;

	Debug.WriteLine(selectedItems.Count);
}

 

BookmarkDockpane.xaml.cs

//added to public partial class BookmarkDockpaneView : UserControl

private void lstBox_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
	var listSelectedItems = ((ListBox)sender).SelectedItems;

	var vm = (BookmarkDockpaneViewModel)this.DataContext;
	vm.RetrieveSelectedBookmarksCommand.Execute(listSelectedItems);
}

 

BookmarkDockpane.xaml

<ListBox Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" Name="LstBookmarks"  SelectionMode="Extended"
		 ItemsSource="{Binding ListOfBookmarks}" Margin="5" 
		 DisplayMemberPath="Name" SelectionChanged ="lstBox_OnSelectionChanged"
		 BorderBrush="{DynamicResource Esri_BorderBrush}" BorderThickness="2"
		 ItemContainerStyle="{DynamicResource Esri_ListBoxItemHighlightBrush}"/>

 

0 Kudos
Wolf
by Esri Regular Contributor
Esri Regular Contributor
0 Kudos