c# - 如何获得 ContentPresenter 的父 ItemsControl?
问题描述
我有一个从这个问题的答案修改的拖拽行为。几乎一切正常,除非我将形状拖过其他形状。这是我的 ItemsControl 的 XAML:
<ItemsControl x:Name="audioDisplayItemsControl"
ItemsSource="{Binding Shapes}">
<ItemsControl.Resources>
<DataTemplate DataType="{x:Type ct:Rectangle}">
<Rectangle Width="{Binding Width}"
Height="{Binding Height}"
Fill="Black"
IsManipulationEnabled="True"/>
</DataTemplate>
<DataTemplate DataType="{x:Type ct:Line}">
<!-- Points reletive to ItemContainer -->
<Line X1="0"
Y1="0"
X2="0"
Y2="{Binding Length}"
Stroke="Gray"
StrokeThickness="2"
StrokeDashArray="4 1"/>
</DataTemplate>
<DataTemplate DataType="{x:Type ct:LabeledLine}">
<Grid>
<!-- Points reletive to ContentPresenter-->
<Line X1="0"
Y1="0"
X2="0"
Y2="{Binding Length}"
Stroke="Red"
StrokeThickness="2"/>
<TextBlock Margin="4,1,0,0" Foreground="White">
<Run Text="("/>
<Run Text="{Binding Num}"/>
<Run Text=") "/>
<Run Text="{Binding Title}"/>
</TextBlock>
</Grid>
</DataTemplate>
</ItemsControl.Resources>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas>
<Canvas.Background>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="Black"/>
<GradientStop Color="Black" Offset="0.30"/>
<GradientStop Color="Green" Offset="0.33"/>
<GradientStop Color="Green" Offset="0.67"/>
<GradientStop Color="Black" Offset="0.7"/>
<GradientStop Color="Black" Offset="1"/>
</LinearGradientBrush>
</Canvas.Background>
</Canvas>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="Canvas.Top" Value="{Binding Top, Mode=TwoWay}"/>
<Setter Property="Canvas.Left" Value="{Binding Left, Mode=TwoWay}"/>
<Setter Property="Panel.ZIndex" Value="{Binding ZIndex}"/>
<Setter Property="ct:DragBehavior.Drag" Value="{Binding CanDrag}"/> <----- DragBehavior attached here
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
只有红线 ( ct:LabeledLine
) 是可拖动的,并且只能沿 x 轴拖动。我的问题是当我将一条红线拖过右侧的红线时,如图所示
“(0) New 0”的红线越过了“(1) New 1”的红线,但没有越过“(1) New 1”的文本。由于 (0) 是在 (1) 之前添加的,因此ContentPresenter
for (0) 在ContentPresenter
for (1) 之后。现在我不能再拖动 (0),除非我将 (1) 移开。这是因为拖动行为附加到contentPresenter
,而不是红线。
从MouseLeftButtonUp
事件中,我可以得到ContentPresenter
(它只是发件人),但我需要得到父ItemsControl
级,这样我才能得到它的子级列表,按它们的 x 位置值对它们进行排序,并ZIndex
根据它们的排序顺序进行分配。我认为这应该可以解决我的问题。
我只是不知道如何得到父母ItemsControl
。
解决方案
您可以使用VisualTreeHelper.GetParent
.
当我需要做这样的事情时,这是我使用的一种方法:
Public Function FindVisualParent(Of ParentType As DependencyObject)(obj As DependencyObject) As ParentType
Dim Parent As DependencyObject = obj
Do Until Parent Is Nothing OrElse TypeOf Parent Is ParentType
If TypeOf Parent IsNot Visual AndAlso TypeOf Parent IsNot Media3D.Visual3D AndAlso TypeOf Parent Is FrameworkContentElement Then
Parent = DirectCast(Parent, FrameworkContentElement).Parent
Else
Parent = VisualTreeHelper.GetParent(Parent)
End If
Loop
Return Parent
End Function
我花时间将以上内容转换为 C#:
public ParentType FindVisualParent<ParentType>(DependencyObject obj) where ParentType : DependencyObject
{
DependencyObject Parent = obj;
while (Parent != null && !(Parent is ParentType))
{
if (Parent is FrameworkContentElement contentElement)
Parent = contentElement.Parent;
else
Parent = VisualTreeHelper.GetParent(Parent);
}
return (ParentType)Parent;
}
推荐阅读
- python - 如何实时从 mongodb 获取数据到我的 python 应用程序
- python - Python - 在数据框列中查找以元音开头和结尾的单词
- visual-studio - xamarin 的设计视图在 Visual Studio 2019 中不可用
- c++ - 指向结构的数据结构
- php - 仅在使用 PHP 的 S3 存储桶中列出文件夹
- python - Python:列表列表的getter和setter
- python - pcolor 不能正确显示 Z 值
- swiftui - 选择器在数据更改时删除选定的段
- chisel - 为状态机创建字符串调试 Vec
- javascript - 如何保持 react-native-webview 的多个实例打开(并安装),同时能够在它们之间导航(使用 react-navigation)