Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Moving Item to a location next to a disabled item causes the application to freeze #31

Open
zndxcvbn opened this issue Jan 10, 2025 · 1 comment
Labels
bug Something isn't working

Comments

@zndxcvbn
Copy link

There is a situation when there is a disabled item in the DataGrid. This item has the IsEnabled="False" property set. When such an item is at the very top (the first in the DataGrid) and when trying to move any other item above such an item, the program hangs. It seems that the program gets stuck in the BaseDataGridDropHandler.cs > FindDataGridRowFromChildView method in a loop.

Below I have provided an example to reproduce this behavior:

<DataGrid.Styles>
  <Style Selector="DataGridRow" x:DataType="vm:ItemViewModel">
    <Setter Property="Interaction.Behaviors">
      <Setter.Value>
        <BehaviorCollectionTemplate>
          <BehaviorCollection>
            <DataTriggerBehavior Binding="{Binding Title}" Value="Item0">
              <ChangePropertyAction PropertyName="IsEnabled" Value="False" />
            </DataTriggerBehavior>
          </BehaviorCollection>
        </BehaviorCollectionTemplate>
      </Setter.Value>
    </Setter>
  </Style>
</DataGrid.Styles>
@wieslawsoltes wieslawsoltes added the bug Something isn't working label Jan 14, 2025
@zndxcvbn
Copy link
Author

zndxcvbn commented Jan 27, 2025

I tried to track where the cursor goes in the visual tree, it seems it goes beyond the DataGrid:

private static DataGridRow? FindDataGridRowFromChildView(StyledElement sourceChild)
{
    int maxDepth = 16;
    DataGridRow? row = null;
    StyledElement? current = sourceChild;
    while (maxDepth --> 0 || row is null)
    {
        if (current is DataGridRow dgr)
            row = dgr;
     
        Debug.WriteLine($"Traversing to parent: {current.GetType().Name}");
        current = current?.Parent;
    }
    return row;
}

Debug:

Traversing to parent: Rectangle
Traversing to parent: Grid
Traversing to parent: Border
Traversing to parent: Grid
Traversing to parent: DataGridRowHeader
Traversing to parent: DataGridFrozenGrid
Traversing to parent: Border
Traversing to parent: DataGridRow
Traversing to parent: DataGridRowsPresenter
Traversing to parent: Grid
Traversing to parent: Border
Traversing to parent: DataGrid
Traversing to parent: Grid
Traversing to parent: TabItem
Traversing to parent: TabControl
Traversing to parent: MainWindow

I found a workaround in the following:
BaseDataGridDropHandler.cs

public override bool Validate(object? sender, DragEventArgs e, object? sourceContext, object? targetContext, object? state)
{
    if (e.Source is Control c && sender is DataGrid dg)
    {
        bool valid = Validate(dg, e, sourceContext, targetContext, false);
        if (valid)
        {
            var row = FindDataGridRowFromChildView(c);
            if (row != null)
            {
                string direction = e.Data.Contains("direction") ? (string)e.Data.Get("direction")! : "down";
                ApplyDraggingStyleToRow(row!, direction);
                ClearDraggingStyleFromAllRows(sender, exceptThis: row);
            }
        }
        return valid;
    }
    ClearDraggingStyleFromAllRows(sender);
    return false;
}
private static DataGridRow? FindDataGridRowFromChildView(StyledElement sourceChild)
{
    int maxDepth = 16;
    DataGridRow? row = null;
    StyledElement? current = sourceChild;
    while (maxDepth --> 0 || row is null)
    {
        if (current is DataGridRow dgr)
        {
            row = dgr;
            break;
        }
        if (current is DataGrid)
        {
            break;
        }

        current = current?.Parent;
    }
    return row;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants