将 dragablz:TabablzControl 选项卡拖到前面
Dragging over a dragablz:TabablzControl tab to bring it to front
我想为我的 dragablz:TabablzControl 的每个 TabItem 实现一个 DragEnter-Event。将文件拖到上面时,应自动选择标签。
我在 Whosebug 上发现了两个与我的问题相似的主题:
- Dragging over a tab to bring to front
- WPF选项卡控件拖动'n
drop: 把制表符放在前面 behavior
不幸的是,这些解决方案不适用于来自 Dragablz 的 TabablzControl。
<dragablz:TabablzControl Name="TC_FooBar" FixedHeaderCount="3">
<TabItem Header="FIRST">
<!-- <ContentOfFirstTabItem/> -->
</TabItem>
<TabItem Header="SECOND">
<!-- <ContentOfSecondTabItem/> -->
</TabItem>
<TabItem Header="THIRD">
<!-- <ContentOfThirdTabItem/> -->
</TabItem>
</dragablz:TabablzControl>
到目前为止我尝试过的:
- 为每个 TabItem 和 TabablzControl 本身实施
DragEnter
和 PreviewDragEnter
事件。
- 为 TabablzControl 和每个 TabItem 设置
AllowDrop="True"
。
每次 e.Source
等于当前所选选项卡的内容。我无法识别正确的 TabItem。有什么想法吗?
这很简单。
您已经准备好正确的设置:
<dragablz:TabablzControl DragEnter="TabControl_OnDragEnter" AllowDrop="True">
<TabItem Header="FIRST"/>
<TabItem Header="SECOND"/>
<TabItem Header="THIRD"/>
</dragablz:TabablzControl>
AllowDrop
是 true
并且有一个 DragEnter
路由事件处理程序。请注意,这是冒泡事件,但您也可以使用隧道 PreviewDragEnter
版本。
魔术将在事件处理程序中发生。我们需要 OriginalSource
属性。但是,这将是一些 Visual
代表 TabItem
,而不是 TabItem
本身!您应该阅读 WPF 的样式和模板功能以获取更多信息。
我们所需要的只是从代表 Visual
到实际的 TabItem
。我们可以通过沿着可视化树向上移动直到找到项目来完成:
private void TabControl_OnDragEnter(object sender, DragEventArgs e)
{
// Just a sanity check - we need a Visual here
if (!(e.OriginalSource is Visual v))
{
return;
}
// DragablzItems will represent our TabItems, so we search for those
var item = GetParentOfType<DragablzItem>(v);
// DragablzItem.Content should contain our original TabItem
if (item != null && item.Content is TabItem ti)
{
ti.IsSelected = true;
}
}
辅助 GetParentOfType
方法可能如下所示:
static T GetParentOfType<T>(Visual visual) where T : Visual
{
DependencyObject parent = visual;
do
{
parent = VisualTreeHelper.GetParent(parent);
} while (parent != null && !(parent is T));
return parent as T;
}
我想为我的 dragablz:TabablzControl 的每个 TabItem 实现一个 DragEnter-Event。将文件拖到上面时,应自动选择标签。
我在 Whosebug 上发现了两个与我的问题相似的主题:
- Dragging over a tab to bring to front
- WPF选项卡控件拖动'n drop: 把制表符放在前面 behavior
不幸的是,这些解决方案不适用于来自 Dragablz 的 TabablzControl。
<dragablz:TabablzControl Name="TC_FooBar" FixedHeaderCount="3">
<TabItem Header="FIRST">
<!-- <ContentOfFirstTabItem/> -->
</TabItem>
<TabItem Header="SECOND">
<!-- <ContentOfSecondTabItem/> -->
</TabItem>
<TabItem Header="THIRD">
<!-- <ContentOfThirdTabItem/> -->
</TabItem>
</dragablz:TabablzControl>
到目前为止我尝试过的:
- 为每个 TabItem 和 TabablzControl 本身实施
DragEnter
和PreviewDragEnter
事件。 - 为 TabablzControl 和每个 TabItem 设置
AllowDrop="True"
。
每次 e.Source
等于当前所选选项卡的内容。我无法识别正确的 TabItem。有什么想法吗?
这很简单。
您已经准备好正确的设置:
<dragablz:TabablzControl DragEnter="TabControl_OnDragEnter" AllowDrop="True">
<TabItem Header="FIRST"/>
<TabItem Header="SECOND"/>
<TabItem Header="THIRD"/>
</dragablz:TabablzControl>
AllowDrop
是 true
并且有一个 DragEnter
路由事件处理程序。请注意,这是冒泡事件,但您也可以使用隧道 PreviewDragEnter
版本。
魔术将在事件处理程序中发生。我们需要 OriginalSource
属性。但是,这将是一些 Visual
代表 TabItem
,而不是 TabItem
本身!您应该阅读 WPF 的样式和模板功能以获取更多信息。
我们所需要的只是从代表 Visual
到实际的 TabItem
。我们可以通过沿着可视化树向上移动直到找到项目来完成:
private void TabControl_OnDragEnter(object sender, DragEventArgs e)
{
// Just a sanity check - we need a Visual here
if (!(e.OriginalSource is Visual v))
{
return;
}
// DragablzItems will represent our TabItems, so we search for those
var item = GetParentOfType<DragablzItem>(v);
// DragablzItem.Content should contain our original TabItem
if (item != null && item.Content is TabItem ti)
{
ti.IsSelected = true;
}
}
辅助 GetParentOfType
方法可能如下所示:
static T GetParentOfType<T>(Visual visual) where T : Visual
{
DependencyObject parent = visual;
do
{
parent = VisualTreeHelper.GetParent(parent);
} while (parent != null && !(parent is T));
return parent as T;
}