在鼠标输入或拖动完成时锁定 ContentPresenter 的 zIndex
Lock zIndex of a ContentPresenter Upon Mouse Enter or Drag Complete
我需要在 canvas/content 控件被 Thumb
拖动后锁定它的 Z 顺序。
在下图中,当鼠标悬停处于活动状态时,"Joe Smith" 在其他两个椭圆上方弹出。一旦拖动停止并且鼠标移出,它就会回到它的值。
我无法在下面显示的设计中找到解决方案,以将其锁定在其他设计之上。
最小可重现示例
我创建了包含 xaml、拇指 class 和人员 class 的所有代码的 code gist。所要做的就是创建一个 .Net Core WPF 应用程序并放入代码片段并根据需要在 Xaml 中设置名称间距。
设计
有一个 ItemsControl
,其中 DataTemplate
定义为 Canvas
。 ItemsControl
中的每个内容都有 ContentControl
,其中有一个 Thumb
被样式应用。
鼠标进入 ContentPresenter
的另一种样式触发器通过设置内容的内部 [=20] 将内容 临时 推入 zIndex
高于其他内容=] 的 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>
查看 Gist 以了解所有支持的 classes 和样式以重现
实际设计
最终目标是拥有一个固定大小的图像面板,当用户抓住拇指时,图像将向前移动并锁定在其他图像之上。我这样说是为了防止有另一种方法可以在最小示例设计之上提供答案。
在我的 ItemsControl
中,我将 ItemsPanelTemplate
更改为 Canvas
例如
<ItemsPanelTemplate>
<Canvas x:Name="MainCanvas" />
</ItemsPanelTemplate>
当查看用户单击 ContentControl
的可视化树时,它有一个 Canvas
的父级,该 ContentPresenter
具有顶级 [=15] =] 例如(见命名MainCanvas
):
我将 ContentControl
更改为有一个 MouseEnter
事件:
<ContentControl Width="100" Height="100" MouseEnter="EnterMouse">
<Grid>
<Ellipse Fill="Silver">
在该方法中,我需要找到命名的 "MainCanvas" Canvas
并枚举其所有子项 ContentPresenter
并提取最大 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);
}
我需要在 canvas/content 控件被 Thumb
拖动后锁定它的 Z 顺序。
在下图中,当鼠标悬停处于活动状态时,"Joe Smith" 在其他两个椭圆上方弹出。一旦拖动停止并且鼠标移出,它就会回到它的值。
我无法在下面显示的设计中找到解决方案,以将其锁定在其他设计之上。
最小可重现示例
我创建了包含 xaml、拇指 class 和人员 class 的所有代码的 code gist。所要做的就是创建一个 .Net Core WPF 应用程序并放入代码片段并根据需要在 Xaml 中设置名称间距。
设计
有一个 ItemsControl
,其中 DataTemplate
定义为 Canvas
。 ItemsControl
中的每个内容都有 ContentControl
,其中有一个 Thumb
被样式应用。
鼠标进入 ContentPresenter
的另一种样式触发器通过设置内容的内部 [=20] 将内容 临时 推入 zIndex
高于其他内容=] 的 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>
查看 Gist 以了解所有支持的 classes 和样式以重现
实际设计
最终目标是拥有一个固定大小的图像面板,当用户抓住拇指时,图像将向前移动并锁定在其他图像之上。我这样说是为了防止有另一种方法可以在最小示例设计之上提供答案。
在我的 ItemsControl
中,我将 ItemsPanelTemplate
更改为 Canvas
例如
<ItemsPanelTemplate>
<Canvas x:Name="MainCanvas" />
</ItemsPanelTemplate>
当查看用户单击 ContentControl
的可视化树时,它有一个 Canvas
的父级,该 ContentPresenter
具有顶级 [=15] =] 例如(见命名MainCanvas
):
我将 ContentControl
更改为有一个 MouseEnter
事件:
<ContentControl Width="100" Height="100" MouseEnter="EnterMouse">
<Grid>
<Ellipse Fill="Silver">
在该方法中,我需要找到命名的 "MainCanvas" Canvas
并枚举其所有子项 ContentPresenter
并提取最大 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);
}