Блокировка zIndex для ContentPresenter при нажатии мыши Enter или Drag Complete - PullRequest
0 голосов
/ 14 февраля 2020

Мне нужно заблокировать Z-порядок элемента управления canvas / content после его перетаскивания на Thumb.

На изображении ниже «Джо Смит» выскакивает над двумя другими эллипсами, когда наведен курсор мыши. Как только перетаскивание прекращается и мышь выходит, она возвращается к своему значению.

Я не могу найти решение в дизайне, который я показал ниже, чтобы держать его запертым над остальными.

Joe moves in front, only to be dropped back behind Jenny.


Пример минимальной воспроизводимости

Я создал суть кода всего кода, который содержит xaml, класс thumb и класс people. Все, что нужно сделать, - это создать приложение. Net Core WPF, добавить фрагменты кода и установить интервал имен в Xaml по мере необходимости.


Дизайн Существует ItemsControl, для которого DataTemplate определено с Canvas. Каждый контент в ItemsControl имеет ContentControl, который имеет Thumb в соответствии со стилем.

Другой триггер стиля мыши, входящей в ContentPresenter, имеет содержимое временно , помещенное на zIndex над остальными, устанавливая внутреннее Grid содержимого zIndex в 1 .

Как придерживаться , что zIndex?

Xaml

<ItemsControl Margin="10" ItemsSource="{Binding Source={StaticResource People}}">

    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <UniformGrid Rows="1" />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>

    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Canvas>
                <ContentControl  Width="100" Height="100" >
                    <Grid>
                        <Ellipse Fill="Silver">
                            <Ellipse.Effect>
                                <DropShadowEffect Color="Black" Direction="320"  ShadowDepth="6"  Opacity="0.5"/>
                            </Ellipse.Effect>
                        </Ellipse>
                        <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
                            <TextBlock Margin="3,3,3,0" Text="{Binding Path=First}"/>
                            <TextBlock Margin="3,0,3,7" Text="{Binding Path=Last}"/>
                        </StackPanel>
                    </Grid>
                </ContentControl>
            </Canvas>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
    <ItemsControl.ItemContainerStyle>
        <Style TargetType="{x:Type ContentPresenter}">
            <Style.Triggers>
                <Trigger Property="IsMouseOver" Value="True">
                    <Setter Property="Grid.ZIndex" Value="1"/>
                </Trigger>
            </Style.Triggers>
        </Style>
    </ItemsControl.ItemContainerStyle>
</ItemsControl>

См. Сущность для все поддерживающие классы и стили для воспроизведения


Фактический дизайн

Конечная цель состоит в том, чтобы иметь панель изображений заданного размера, когда пользователь хватает большим пальцем изображение, которое он будет перемещать вперед и блокировать над остальными. Я говорю это в случае, если есть другой способ сделать это, который мог бы дать ответ выше минимального примера дизайна.

1 Ответ

1 голос
/ 06 апреля 2020

В моем ItemsControl я изменил ItemsPanelTemplate на Canvas, например

<ItemsPanelTemplate>
    <Canvas x:Name="MainCanvas" />
</ItemsPanelTemplate>

, который при просмотре дерева визуалов, где пользователь нажимал ContentControl, имел родительский элемент Canvas, который имел ContentPresenter с этим верхним уровнем Canvas, например ( см. с именем MainCanvas):

Visual tree

Я изменил ContentControl, чтобы иметь событие MouseEnter:

<ContentControl  Width="100" Height="100" MouseEnter="EnterMouse">
   <Grid>
       <Ellipse Fill="Silver">

В этом методе мне нужно было найти названный "MainCanvas" Canvas и перечислить все его присваивает ContentPresenter s и извлекает максимальное значение ZIndex, а затем задает для моего ContentControl (показано синим цветом выше) значение ZIndex плюс 1.

Вот код, из которого извлекаются необходимые родители:

private void EnterMouse(object sender, MouseEventArgs e)
{
    if (sender is ContentControl cc)
    {
        var cpParent = FindParent<ContentPresenter>(cc);
        var p2 = FindParent<Canvas>(cpParent);

        var max = p2.Children.Cast<UIElement>().Max(control => Panel.GetZIndex(control));
        Panel.SetZIndex(cpParent, max + 1);
    }
}

private T FindParent<T>(DependencyObject child) where T : DependencyObject
{
    DependencyObject immediateParent = VisualTreeHelper.GetParent(child);

    T parent = immediateParent as T;

    return parent ?? FindParent<T>(immediateParent);
}
...