Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6792737
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 26, 20262026-05-26T18:00:29+00:00 2026-05-26T18:00:29+00:00

I have two views of some data: a list view (a ListBox now, but

  • 0

I have two views of some data: a list view (a ListBox now, but I’ve been meaning to switch to ListView) and a fancy graphical representation on a map. In either view the user can click an object and it will be selected in both views. Multiselect is also possible, so each ViewModel instance has its own IsSelected property.

Currently I’m binding ListBoxItem.IsSelected to ViewModel.IsSelected, but this only works properly if the ListBox is NOT virtualizing (see here). Unfortunately, disabling virtualization hurts performance and my app has become too slow.

So I have to enable virtualization again. In order to maintain the ViewModel.IsSelected property of off-screen items, I noticed that ListBox and ListView have a SelectionChanged event that I can (presumably) use to propagate the selection state from the ListBox/ListView to the ViewModel.

My question is, how do I propagate selection state in the reverse direction? The SelectedItems property of ListBox/ListView is read-only! Suppose the user clicks an item in the graphical representation, but it is off-screen w.r.t. the list. If I just set ViewModel.IsSelected then the ListBox/ListView will be unaware of the new selection, and as a consequence it will fail to deselect that item if the user clicks a different item in the list. I could call ListBox.ScrollIntoView from the ViewModel, but there are a couple of problems:

  • In my UI it’s actually possible to select two items with one click if they are in the same location graphically, although they may be located in completely different locations in the ListBox/ListView.
  • It breaks ViewModel isolation (my ViewModel is totally unaware of WPF and I’d like to keep it that way.)

So, my dear WPF experts, any thoughts?

EDIT: I ended up switching to an Infragistics control and using an ugly and rather slow solution. The point is, I no longer need an answer.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-26T18:00:30+00:00Added an answer on May 26, 2026 at 6:00 pm

    You can create a Behavior that synchronizes ListBox.SelectedItems with a collection in your ViewModel:

    public class MultiSelectionBehavior : Behavior<ListBox>
    {
        protected override void OnAttached()
        {
            base.OnAttached();
            if (SelectedItems != null)
            {
                AssociatedObject.SelectedItems.Clear();
                foreach (var item in SelectedItems)
                {
                    AssociatedObject.SelectedItems.Add(item);
                }
            }
        }
    
        public IList SelectedItems
        {
            get { return (IList)GetValue(SelectedItemsProperty); }
            set { SetValue(SelectedItemsProperty, value); }
        }
    
        public static readonly DependencyProperty SelectedItemsProperty =
            DependencyProperty.Register("SelectedItems", typeof(IList), typeof(MultiSelectionBehavior), new UIPropertyMetadata(null, SelectedItemsChanged));
    
        private static void SelectedItemsChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
        {
            var behavior = o as MultiSelectionBehavior;
            if (behavior == null)
                return;
    
            var oldValue = e.OldValue as INotifyCollectionChanged;
            var newValue = e.NewValue as INotifyCollectionChanged;
    
            if (oldValue != null)
            {
                oldValue.CollectionChanged -= behavior.SourceCollectionChanged;
                behavior.AssociatedObject.SelectionChanged -= behavior.ListBoxSelectionChanged;
            }
            if (newValue != null)
            {
                behavior.AssociatedObject.SelectedItems.Clear();
                foreach (var item in (IEnumerable)newValue)
                {
                    behavior.AssociatedObject.SelectedItems.Add(item);
                }
    
                behavior.AssociatedObject.SelectionChanged += behavior.ListBoxSelectionChanged;
                newValue.CollectionChanged += behavior.SourceCollectionChanged;
            }
        }
    
        private bool _isUpdatingTarget;
        private bool _isUpdatingSource;
    
        void SourceCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            if (_isUpdatingSource)
                return;
    
            try
            {
                _isUpdatingTarget = true;
    
                if (e.OldItems != null)
                {
                    foreach (var item in e.OldItems)
                    {
                        AssociatedObject.SelectedItems.Remove(item);
                    }
                }
    
                if (e.NewItems != null)
                {
                    foreach (var item in e.NewItems)
                    {
                        AssociatedObject.SelectedItems.Add(item);
                    }
                }
    
                if (e.Action == NotifyCollectionChangedAction.Reset)
                {
                    AssociatedObject.SelectedItems.Clear();
                }
            }
            finally
            {
                _isUpdatingTarget = false;
            }
        }
    
        private void ListBoxSelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (_isUpdatingTarget)
                return;
    
            var selectedItems = this.SelectedItems;
            if (selectedItems == null)
                return;
    
            try
            {
                _isUpdatingSource = true;
    
                foreach (var item in e.RemovedItems)
                {
                    selectedItems.Remove(item);
                }
    
                foreach (var item in e.AddedItems)
                {
                    selectedItems.Add(item);
                }
            }
            finally
            {
                _isUpdatingSource = false;
            }
        }
    
    }
    

    This behavior can be used as shown below:

            <ListBox ItemsSource="{Binding Items}"
                     DisplayMemberPath="Name"
                     SelectionMode="Extended">
                <i:Interaction.Behaviors>
                    <local:MultiSelectionBehavior SelectedItems="{Binding SelectedItems}" />
                </i:Interaction.Behaviors>
            </ListBox>
    

    (note that the SelectedItems collection in your ViewModel has to be initialized; the behavior won’t set it, it will only change its content)

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I try to have some inheritance with attributeBindings between two View. (function(exports) { Ember.MobileBaseView
I have two views, both under the NavigationController. I don't want View 1 (on
I have two views in my ViewFlipper . One of views contains a ListView
I have two views, one view takes the whole screen, the second view covers
I have two views within one .xib (one view for landscape, another for portrait).
I have two views.In first view, I have a table view and I am
I have two activities one displaying map view and another listview, the main objective
I have a list view with two colums in wpf Customername and Isvalid.I am
This has been killing me for two days now. I have a main Activity
This has been killing me for two days now. I have a main Activity

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.