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/DockpaneSimple%20(C%23).md
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
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 StateError XDG0013 The property "SelectedItems" does not have an accessible setter.
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 -->
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}"/>
You can look at this sample: arcgis-pro-sdk-community-samples/Framework/RemoveAddins at master · Esri/arcgis-pro-sdk-community-samples (github.com)
Přihlášení členové mohou přispívat, sledovat aktualizace a další. Jste tu noví? Zaregistrujte si bezplatný účet.
Find useful guides, FAQs, and documents to help you navigate and make the most of Esri Community.