Search code examples
c#wpfxamlavalondockxceed

DataGrid loses selection


There is a collection of categories with products.

Each category is represented in the interface by the AvalonDock tab, which has a DataGrid with products.

Now when switching from tab to tab, DataGrid updates the collection every time. If you select a pair of rows in the table on the first tab, switch to the second tab and return to the first one, the selection disappears.

What could be the problem?

XAML:

<xcad:DockingManager DocumentsSource="{Binding Examples}">
    <xcad:DockingManager.LayoutItemTemplate>
        <DataTemplate>
            <ListBox ItemsSource="{Binding Content.Items}" 
                     SelectionMode="Extended" />
        </DataTemplate>
    </xcad:DockingManager.LayoutItemTemplate>
    <xcad:LayoutRoot />
</xcad:DockingManager>>

Code-behind:

public partial class MainWindow : Window
{
    public class Example
    {
        public List<int> Items { get; } = new List<int>();

        public Example()
        {
            for (var i = 0; i < 10; i++)
            {
                Items.Add(i);
            }
        }
    }

    public List<Example> Examples { get; } = new List<Example>();

    public MainWindow()
    {
        InitializeComponent();
        DataContext = this;
        Examples.Add(new Example());
        Examples.Add(new Example());
    }
}

enter image description here


Solution

  • As @nobody suggested, switching between tabs seems to update the layout, and the selection state is lost. If UI can't persist the selection state, then you can use the next layer i.e. presentation or view-model to do the same.

    In this case, adding a IsSelected property to view-model item and a binding to ListViewItem should do the trick.

    enter image description here

    XAML:

    <Grid>
        <xcad:DockingManager DocumentsSource="{Binding Examples}">
            <xcad:DockingManager.DocumentHeaderTemplate>
                <DataTemplate>
                    <TextBlock Text="Doc" />
                </DataTemplate>
            </xcad:DockingManager.DocumentHeaderTemplate>
            <xcad:DockingManager.LayoutItemTemplate>
                <DataTemplate>
                    <ListBox 
                        DisplayMemberPath="Value"
                        ItemsSource="{Binding Content.Items}" 
                        SelectionMode="Extended">
                        <ListBox.Resources>
                            <SolidColorBrush x:Key="{x:Static SystemColors.InactiveSelectionHighlightBrushKey}" Color="LightBlue" />
                            <Style TargetType="{x:Type ListBoxItem}">
                                <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" />
                            </Style>
                        </ListBox.Resources>
                    </ListBox>
                </DataTemplate>
            </xcad:DockingManager.LayoutItemTemplate>
            <xcad:LayoutRoot />
        </xcad:DockingManager>
    </Grid>
    

    Code-behind:

    public partial class MainWindow : Window
    {
        public class ExampleItem
        {
            public int Value { get; set; }
            public bool IsSelected { get; set; }
        }
        public class Example
        {
            public List<ExampleItem> Items { get; } = new List<ExampleItem>();
    
            public Example()
            {
                for (var i = 0; i < 10; i++)
                {
                    Items.Add(new ExampleItem { Value = i });
                }
            }
        }
    
        public List<Example> Examples { get; } = new List<Example>();
    
        public MainWindow()
        {
            InitializeComponent();
            DataContext = this;
            Examples.Add(new Example());
            Examples.Add(new Example());
        }
    }