Custom Panel with Reorder and animations / transit

2020-07-28 11:23发布

问题:

I have a custom class called FluidPanel that extends Panel and overrides methods MeasureOverride and ArrangeOverride. The goal is to create the Google Keep appearence. Ok, it's working fine. (app link)

But, because I'm extending a basic Panel and using it as the ItemsPanelTemplate, I'm missing 2 things: Reorder and some transitions, that simply doens't work out of the box. See code:

<GridView CanReorderItems="True" CanDrag="True" AllowDrop="True">
    <GridView.ItemContainerTransitions>
        <TransitionCollection>
            <EntranceThemeTransition FromVerticalOffset="200" IsStaggeringEnabled="True"/>
            <ReorderThemeTransition/>
        </TransitionCollection>
    </GridView.ItemContainerTransitions>

    <GridView.ItemsPanel>
        <ItemsPanelTemplate>
            <local:FluidPanel/><!--custom panel = reorder doesn't work-->
            <!--<StackPanel/>--><!--reorder and animations work normally (reorder to see)-->
        </ItemsPanelTemplate>
    </GridView.ItemsPanel>

    <Grid Width="50" Height="50" Background="Red"/>
    <Grid Width="50" Height="50" Background="Green"/>
    <Grid Width="50" Height="50" Background="Blue"/>
    <Grid Width="50" Height="50" Background="Orange"/>
    <Grid Width="50" Height="50" Background="Purple"/>
    <Grid Width="50" Height="50" Background="Pink"/>
</GridView>

So, the main question is: How to create a custom Panel with Reorder fully working, including animations? (like that offset to the left/right/...)

A second (less important) question is: And with the EntranceThemeTransition working?

回答1:

I partially found the solution.
Unfortunately it's not as easy as it should be.

For custom Panels, it seems that we have to implement the Reorder manually, listening to the drag & drop events.

Here is an article about it: Extending GridView with Drag and Drop
and here is a simplified code about it.

The reorder animation is added by manually changing the Visual State:

private void OnDragOver(object sender, DragEventArgs e)
{
    var item = (e.OriginalSource as FrameworkElement).DataContext as Note;
    if (item == null) return;

    e.Data.Properties["targetItem"] = item;

    var itemContainer = (sender as ItemsControl).ContainerFromItem(item) as Control;
    if (itemContainer == null) return;

    VisualStateManager.GoToState(itemContainer, "BottomReorderHint", true);
}

But I still hope there is any easier way to do it, giving the fact that a lot of Panels implement it (StackPanel, ItemsWrapGrid, ...).

Still can't get the EntranceThemeTransition to work on the custom panel.
EDIT: workaround to make EntranceThemeTransition works