dotnet/wpf · error

View can't be shared by more than one ListView.

Error message

View can't be shared by more than one ListView.

What it means

ListView throws this InvalidOperationException in its View property change callback (OnViewChanged) when the ViewBase instance being assigned is already in use by another ListView. Each ViewBase tracks an IsUsed flag because the ListView stores per-view item/container state on it; sharing one view instance across multiple ListViews would corrupt that state, so the assignment is rejected.

Solutions

  1. Create a new ViewBase (e.g. new GridView()) for each ListView instead of sharing one instance.
  2. If the view is declared in resources, add x:Shared="False" so each lookup produces a fresh instance.
  3. To move a view between lists, first set the old ListView's View to null and ensure IsUsed is reset before assigning.
  4. Check view.IsUsed before assignment and create a fresh copy when it returns true.

Example fix

// before: listView1.View = shared; listView2.View = shared; (throws InvalidOperationException) // after: listView1.View = new GridView { Columns = { new GridViewColumn { Header = "Name" } } }; listView2.View = new GridView { Columns = { new GridViewColumn { Header = "Name" } } };
Defensive patterns

Strategy: validation

Validate before calling

static bool CanAssignView(ListView listView, ViewBase view) => view == null || ReferenceEquals(listView.View, view) || !view.IsUsed;

Type guard

static bool IsViewUnshared(ViewBase view) => view != null && !view.IsUsed;

Try / catch

try { listView.View = view; } catch (InvalidOperationException ex) when (ex.Message.Contains("shared")) { listView.View = CreateFreshView(); }

Prevention

When it happens

Trigger: Setting ListView.View (via code, XAML resource, style, or binding) to a ViewBase whose IsUsed is already true — e.g. assigning the same GridView instance to two ListView.View properties, or re-assigning a view still held by a previous ListView.

Common situations: Declaring one GridView as a shared XAML resource used by multiple ListViews; creating a single view object in code and applying it to several lists in a loop; moving a view between lists without first detaching it.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/38882b8ff0e6457f. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/ListView.cs:93

        /// descriptor of the whole view. Include chrome/layout/item/...
        /// </summary>
        public ViewBase View
        {
            get { return (ViewBase)GetValue(ViewProperty); }
            set { SetValue(ViewProperty, value); }
        }

        private static void OnViewChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ListView listView = (ListView)d;

            ViewBase oldView = (ViewBase)e.OldValue;
            ViewBase newView = (ViewBase)e.NewValue;
            if (newView != null)
            {
                if (newView.IsUsed)
                {
                    throw new InvalidOperationException(SR.ListView_ViewCannotBeShared);
                }
                newView.IsUsed = true;
            }

            // In ApplyNewView ListView.ClearContainerForItemOverride will be called for each item.
            // Should use old view to do clear item.
            listView._previousView = oldView;
            listView.ApplyNewView();
            // After ApplyNewView, if item is removed, ListView.ClearContainerForItemOverride will be called.
            // Then should use new view to do clear item.
            listView._previousView = newView;

            //Switch ViewAutomationPeer in ListViewAutomationPeer
            ListViewAutomationPeer lvPeer = UIElementAutomationPeer.FromElement(listView) as ListViewAutomationPeer;
            if (lvPeer != null)
            {
                lvPeer.ViewAutomationPeer?.ViewDetached();

View on GitHub (pinned to 81131a70a4)