是否可以在wpf的选项卡控件中重新排列选项卡项?

是否可以在wpf的选项卡控件中重新排列选项卡项?,wpf,wpf-controls,wpftoolkit,Wpf,Wpf Controls,Wpftoolkit,是否可以在运行时重新排列选项卡控件中的选项卡项?例如,我有3个关于汽车的选项卡项和4个关于房子的选项卡项。我想能够重新安排他们使用拖放。这是可能的还是神奇的 我这里有一个选项卡控件是XAML <TabControl x:Name="tc" Visibility="Collapsed" GotFocus="Focus" AllowDrop="True" > </TabControl> 选项卡项将在运行时添加。 谢谢你帮助我 在MSDN论坛中找到

是否可以在运行时重新排列选项卡控件中的选项卡项?例如,我有3个关于汽车的选项卡项和4个关于房子的选项卡项。我想能够重新安排他们使用拖放。这是可能的还是神奇的

我这里有一个选项卡控件是XAML

<TabControl x:Name="tc" Visibility="Collapsed" GotFocus="Focus" AllowDrop="True" >
            </TabControl>

选项卡项将在运行时添加。
谢谢你帮助我

在MSDN论坛中找到了解决方案

以下是链接:

以下是解决方案:

C#解决方案

WPF代码:

<TabControl>
    <TabControl.Resources>
        <Style TargetType="TabItem">
            <Setter Property="AllowDrop" Value="True"/>
                <EventSetter Event="PreviewMouseMove" Handler="TabItem_PreviewMouseMove"/>
                <EventSetter Event="Drop" Handler="TabItem_Drop"/>
        </Style>
    </TabControl.Resources>

    <TabItem Header="Tabitem 1"/>
    <TabItem Header="Tabitem 2"/>
    <TabItem Header="Tabitem 3"/>
    <TabItem Header="Tabitem 4"/>
    <TabItem Header="Tabitem 5"/>
</TabControl>
private void TabItem_PreviewMouseMove(object sender, MouseEventArgs e)
{
    if (!(e.Source is TabItem tabItem))
    {
        return;
    }

    if (Mouse.PrimaryDevice.LeftButton == MouseButtonState.Pressed)
    {
        DragDrop.DoDragDrop(tabItem, tabItem, DragDropEffects.All);
    }
}

private void TabItem_Drop(object sender, DragEventArgs e)
{
    if (e.Source is TabItem tabItemTarget &&
        e.Data.GetData(typeof(TabItem)) is TabItem tabItemSource &&
        !tabItemTarget.Equals(tabItemSource) &&
        tabItemTarget.Parent is TabControl tabControl)
    {
        int targetIndex = tabControl.Items.IndexOf(tabItemTarget);

        tabControl.Items.Remove(tabItemSource);
        tabControl.Items.Insert(targetIndex, tabItemSource);
        tabItemSource.IsSelected = true;
    }
}

当我尝试实现此解决方案时,drop事件触发了两次(移动选项卡,但它们立即将其移回)。我必须添加一个整数来跟踪最后一个选项卡目标索引。我的解决方案是在VB.NET中

'additional variable
Dim lastTabTargetIndex As Integer = Nothing

Private Sub tc1_PreviewMouseMove(sender As Object, e As MouseEventArgs) Handles tc1.PreviewMouseMove

    Dim Tabi = TryCast(e.Source, TabItem)

    If Tabi Is Nothing Then
        Exit Sub
    Else
        If Mouse.PrimaryDevice.LeftButton = MouseButtonState.Pressed Then
            DragDrop.DoDragDrop(Tabi, Tabi, DragDropEffects.All)
        End If
    End If
End Sub

Private Sub tc1_Drop(sender As Object, e As DragEventArgs) Handles tc1.Drop

    Dim tabItemTarget = TryCast(e.Source, TabItem)
    Dim tabItemSource = TryCast(e.Data.GetData(GetType(TabItem)), TabItem)

    If Not tabItemTarget.Equals(tabItemSource) Then
        Dim tabControl = TryCast(tabItemTarget.Parent, TabControl)
        Dim sourceIndex As Integer = tabControl.Items.IndexOf(tabItemSource)
        Dim targetIndex As Integer = tabControl.Items.IndexOf(tabItemTarget)

        'had to use this extra statement
        If sourceIndex <> lastTabTargetIndex Then
            'assign lastTabTargetIndex here
            lastTabTargetIndex = targetIndex
            tabControl.Items.Remove(tabItemSource)
            tabControl.Items.Insert(targetIndex, tabItemSource)
            tabControl.Items.Remove(tabItemTarget)
            tabControl.Items.Insert(sourceIndex, tabItemTarget)
        End If

    End If
End Sub
”附加变量
Dim lastTabTargetIndex为整数=无
私有子tc1_PreviewMouseMove(发送方作为对象,e作为MouseEventArgs)处理tc1.PreviewMouseMove
Dim Tabi=TryCast(例如来源,TabItem)
如果塔比什么都不是
出口接头
其他的
如果Mouse.PrimaryDevice.LeftButton=MouseButtonState.按下,则
DragDrop.DoDragDrop(Tabi,Tabi,DragDropEffects.All)
如果结束
如果结束
端接头
私有子tc1_Drop(发送方作为对象,e作为DragEventArgs)处理tc1.Drop
Dim tabItemTarget=TryCast(例如来源,TabItem)
Dim tabItemSource=TryCast(e.Data.GetData(GetType(TabItem)),TabItem)
如果不是tabItemTarget.Equals(tabItemSource),则
Dim tabControl=TryCast(tabItemTarget.Parent,tabControl)
Dim sourceIndex As Integer=tabControl.Items.IndexOf(tabItemSource)
Dim targetIndex As Integer=tabControl.Items.IndexOf(tabItemTarget)
“必须使用这个额外的语句
如果sourceIndex lastTabTargetIndex,则
'在此处指定lastTabTargetIndex
lastTabTargetIndex=targetIndex
tabControl.Items.Remove(tabItemSource)
tabControl.Items.Insert(targetIndex,tabItemSource)
tabControl.Items.Remove(tabItemTarget)
tabControl.Items.Insert(sourceIndex,tabItemTarget)
如果结束
如果结束
端接头

请给我c#的代码,我们将不胜感激。谢谢。当选项卡项为空时,此代码工作正常,但我的选项卡项具有用户控件,其中有许多UI元素。即使我可以把光标放在文本框中,它也会给我带来错误。鼠标点击在每个UI元素中工作,这不是我想要的。我希望我能向你解释一下。这个错误是我的错。只需添加if(tabItem==null)return;在选项卡Item_PreviewMouseMove处理程序中。但“鼠标点击在每个UI元素中工作,这不是我想要的”是什么意思?当我执行var tabControl=tabItemTarget.Parent作为tabControl时,我得到的tabControl为null;我已经在MVVM模式中使用绑定添加了这些项。在我的情况下,我应该如何找到解决方案。伟大的解决方案!附加建议:如果要重新排序而不是切换选项卡,请取消对最后两行的注释。另外,如果您实现了关闭按钮,请检查是否
!(例如,OriginalSource是按钮)