Megabit / Blazorise

Blazorise is a component library built on top of Blazor with support for CSS frameworks like Bootstrap, Tailwind, Bulma, AntDesign, and Material.
https://blazorise.com/
Other
3.29k stars 532 forks source link

Datagrid SelectedRows not Resetting/Clearing as expected. #3233

Closed Mr-Pearce closed 2 years ago

Mr-Pearce commented 2 years ago

Describe the bug I Have a DataGrid with SelectedRows="@myList" and SelectedRowsChanged="@AddOrRemoveMyList"

When i select a row AddOrRemoveMyList gets hit

private void AddOrRemoveMyList (List<MyType> someList)
{
        myList= someList;
        +adding stuff to another list based on the Selection made
}

The Problem is: If i try to reset the selection like myList= new List<MyType>(); AddOrRemoveMyList is hitting afterwards but not with an empty list but with a list where only the last selected one is in it.

The Selected Ui Items are also not changed. Leading to some weird selections.

To Reproduce Steps to reproduce the behavior:

  1. Create razorPage with code example below.
  2. Start and open The Page
  3. Select Some rows.
  4. Click Reset button

Expected behavior Selection should be Empty, AddOrRemoveMyList shouldn't be hit, and if, then with an empty List of items.

Sample Code

<DataGrid TItem="string" Data="@dataList" Narrow="true" FixedHeader="true" Virtualize="true"
          VirtualizeOptions="@(new VirtualizeOptions() { DataGridHeight="calc(-8px + 70vh) !important", DataGridMaxHeight="calc(-8px + 70vh) !important" })"
          Striped="true" Bordered="true" Filterable="true" Sortable="false" SelectionMode="DataGridSelectionMode.Multiple"
          Responsive="true"
          SelectedRows="@myList"
          SelectedRowsChanged="@AddOrRemoveMyList">
    <DataGridColumn TItem="string" Caption="No">
        <DisplayTemplate>
            @context
        </DisplayTemplate>
    </DataGridColumn>
</DataGrid>
<Button Color="Color.Danger" Clicked="@ResetSelection">Reset</Button>
@code {
    private List<string> dataList = new List<string>() { "a", "b", "c", "d", "e", "f" };
    private List<string> myList = new List<string>();

    private void AddOrRemoveMyList(List<string> someList)
    {
        myList = someList;
        StateHasChanged();
    }

    private void ResetSelection()
    {
        myList = new List<string>();
        // also tried myList = null;
        // myList.Clear();
        StateHasChanged();
    }
}

Screenshots If applicable, add screenshots to help explain your problem.

Additional context Vs 2019 Latest Version 0.9.5.2 net5.0 (5.0.12) Blazor Serverside on Windows

David-Moreira commented 2 years ago

Hello @Mr-Pearce you're right, visually everything remains selected, which is wrong, it should keep up with the currently bound SelectedRows Parameter.

As for the SelectedRows itself, when you reset it to an empty list, it takes in the currently SelectedRow, and that's why it goes back to having one item. For that, a temporary workaround is to discard the SelectedRow management, by always setting it to null permanently:

    SelectedRow="null"

Still, that might not help you alot, since visually it still displays the previously Selected Rows.

We'll fix both problems. Thank you for reporting.

Mr-Pearce commented 2 years ago

Hello @David-Moreira SelectedRow="null" actually helps me.

In my actual blazor app i have the Datagrid (with an actual class with multiple properties) inside an Modal and a Card (See Example down below), There it actually works as expected when setting the SelectedRow = "null".

Here the "Working" Example: Interesting Side note: if you change the Type back to List<string>like the example above it also behaves like the example above not unselecting correctly. Probably most people wont use a Datagrid for a plain List of Strings anyway (i only did in this example actually) but its still strange that it behaves differently.

<Modal @ref="myModal">
    <ModalContent Centered="true" Size="ModalSize.ExtraLarge">
        <ModalHeader>
            <ModalTitle>
                Some Modal Title
            </ModalTitle>
        </ModalHeader>
        <ModalBody>
            <Row>
                <Column ColumnSize="ColumnSize.Is3">
                    <Card>
                        <CardHeader>
                            <CardTitle>Some Card Title</CardTitle>
                        </CardHeader>
                        <CardBody Padding="Padding.Is0" Overflow="Overflow.Auto">
                            <DataGrid TItem="SomeType" Data="@dataList" Narrow="true" FixedHeader="true" Virtualize="true"
                                      VirtualizeOptions="@(new VirtualizeOptions() { DataGridHeight="calc(-8px + 70vh) !important", DataGridMaxHeight="calc(-8px + 70vh) !important" })"
                                      Striped="true" Bordered="true" Filterable="true" Sortable="false" SelectionMode="DataGridSelectionMode.Multiple"
                                      Responsive="true"
                                      SelectedRow="null"
                                      SelectedRows="@myList"
                                      SelectedRowsChanged="@AddOrRemoveMyList">
                                <DataGridColumn TItem="SomeType" Field="@nameof(SomeType.MyProperty1)"  Caption="No" Sortable="false" Filterable="false" />
                                <DataGridColumn TItem="SomeType" Field="@nameof(SomeType.Propberty2)"  Caption="Name" Sortable="false" Filterable="false" />
                            </DataGrid>
                        </CardBody>
                    </Card>
                </Column>
            </Row>
        </ModalBody>
        <ModalFooter>
            <Button Color="Color.Danger" Clicked="@ResetSelection">Reset</Button>
        </ModalFooter>
    </ModalContent>
</Modal>

<Button Color="Color.Danger" Clicked="@OpenModal">Show Modal</Button>

@code {
    private List<SomeType> dataList = new List<SomeType>() { new SomeType(1, "a"), new SomeType(2, "b"), new SomeType(3, "c"), new SomeType(4, "d"), new SomeType(5, "e"), new SomeType(6, "f") };
    private List<SomeType> myList = new List<SomeType>();
    private Modal myModal;

    private async Task OpenModal()
    {
        await myModal.Show();
        myList = dataList.Where(x => x.MyProperty1 == 3).ToList(); //selection from saved data
    }

    private void AddOrRemoveMyList(List<SomeType> someList)
    {
        myList = someList;
    }

    private async Task ResetSelection()
    {
        myList = new List<SomeType>(); //<- dont even needed as the preselection in OpenModal() works allready like intended on opening

        await myModal.Hide();
    }
}

    public class SomeType
    {
        public SomeType(int myProperty1, string propberty2)
        {
            MyProperty1 = myProperty1;
            Propberty2 = propberty2;
        }

        public int MyProperty1 { get; set; }
        public string Propberty2 { get; set; }
    }