C# 重构代码以使用自定义类而不是系统提供的类

C# 重构代码以使用自定义类而不是系统提供的类,c#,winforms,tabs,C#,Winforms,Tabs,嗯,这可能是迄今为止最愚蠢的问题,但我有一个巨大的问题困扰着我。首先,我在运行时使用了Resposition TabItems下的代码示例,以允许在控件中拖放选项卡。问题是我使用了一个名为ExtendedTabPage的自定义TabPage类,这给我带来了麻烦。我尝试将转换为关键字,但我运气不好,因此我希望有人能帮助我如何重构代码以允许拖动自定义选项卡 编辑:我忘了提到ExtendedTabPage是由我的对象继承的抽象类(例如,我的一个窗口属于继承ExtendedTabPage的Console

嗯,这可能是迄今为止最愚蠢的问题,但我有一个巨大的问题困扰着我。首先,我在运行时使用了Resposition TabItems下的代码示例,以允许在控件中拖放选项卡。问题是我使用了一个名为
ExtendedTabPage
的自定义TabPage类,这给我带来了麻烦。我尝试将
转换为
关键字,但我运气不好,因此我希望有人能帮助我如何重构代码以允许拖动自定义选项卡

编辑:我忘了提到ExtendedTabPage是由我的对象继承的抽象类(例如,我的一个窗口属于继承ExtendedTabPage的ConsoleTab类)。这与问题本身有关吗

编辑2:重大发现-在DragOver方法中,如果我尝试在typeof语句中使用ConsoleTab,它似乎工作得非常好。问题是,我不想专门针对这个类这样做,而是针对从其父类继承的所有类,它是抽象的(如果需要,我实际上可以将它转换为非抽象的,但我不会主动使用它…)

编辑3:也许一个好方法是直接使用索引交换,避免使用TabPage数据,但是我对如何做到这一点有点困惑

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using ReCodeConsole.Properties;

namespace ReCodeConsole.Core
{
    /// <summary>
    /// Implements all the extra functionality needed for tab pages on top of the existing TabControl.
    /// Includes events for DrawItem, MouseMove and MouseDown.
    /// </summary>
    public partial class ExtendedTabControl : TabControl
    {
        /// <summary>
        /// Initializes a new instance of the ExtendedTabControl class. All events are added.
        /// </summary>
        public ExtendedTabControl() :base()
        {
            this.DrawItem+=new DrawItemEventHandler(DrawTab);
            this.MouseClick+=new MouseEventHandler(Tab_OnMouseDown);
            this.MouseMove+=new MouseEventHandler(Tab_OnMouseMove);
            this.DragOver+=new DragEventHandler(Tab_OnDragOver);
        }
        /// <summary>
        /// Used to store the starting position of a tab drag event.
        /// </summary>
        private Point DragStartPosition = Point.Empty;

        private void DrawTab(object sender, DrawItemEventArgs e)
        {
            //
            //This code will render the close button at the end of the Tab caption.
            //
            e.Graphics.DrawImage(Resources.TabCloseButton, e.Bounds.Right - 22, e.Bounds.Top + 5, 14, 14);
            e.Graphics.DrawString(this.TabPages[e.Index].Text, e.Font, Brushes.Black, e.Bounds.Left + 12, e.Bounds.Top + 3);
            e.DrawFocusRectangle();
        }

        private void Tab_OnMouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            //
            // Regardless of where the MouseDown event originated, save the coordinates for dragging.
            //
            DragStartPosition = new Point(e.X, e.Y);

            #region Close Button Handling
            //
            // Close button code - looping through the controls.
            //
            for (int i = 0; i < this.TabPages.Count; i++)
            {
                Rectangle r = GetTabRect(i);
                //
                //Getting the position of the close button.
                //
                Rectangle closeButton = new Rectangle(r.Right - 22, r.Top + 5, 14, 14);
                if (closeButton.Contains(e.Location))
                {
                    if (this.TabPages[i] is ExtendedTabPage)
                    {
                        if ((this.TabPages[i] as ExtendedTabPage).IsCloseable)
                        {
                            if (MessageBox.Show("Are you sure you want to close this tab?", "Close", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                            {
                                this.TabPages.RemoveAt(i);
                                break;
                            }
                        }
                    }
                    else
                    {
                        if (MessageBox.Show("Are you sure you want to close this tab?", "Close", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                            {
                                this.TabPages.RemoveAt(i);
                                break;
                            }
                     }
                }
            }
            #endregion

        }

        private TabPage HoverTab()
        {
            for (int index = 0; index <= TabCount - 1; index++)
            {
                if (GetTabRect(index).Contains(PointToClient(Cursor.Position)))
                    return (TabPage)TabPages[index];
            }
            return null;
        }

        private void Tab_OnDragOver(object sender, System.Windows.Forms.DragEventArgs e)
        {
            TabPage hover_Tab = HoverTab();
            if (hover_Tab == null)
                e.Effect = DragDropEffects.None;
            else
            {
                if (e.Data.GetDataPresent(typeof(TabPage)))
                {
                    e.Effect = DragDropEffects.Move;
                    TabPage drag_tab = (TabPage)e.Data.GetData(typeof(TabPage));

                    if (hover_Tab == drag_tab) return;

                    Rectangle TabRect = GetTabRect(TabPages.IndexOf(hover_Tab));
                    TabRect.Inflate(-3, -3);
                    if (TabRect.Contains(PointToClient(new Point(e.X, e.Y))))
                    {
                        SwapTabPages(drag_tab, hover_Tab);
                        SelectedTab = drag_tab;
                    }
                }
            }
        }
        private void Tab_OnMouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            if (e.Button != MouseButtons.Left) return;

            Rectangle r = new Rectangle(DragStartPosition, Size.Empty);
            r.Inflate(SystemInformation.DragSize);

            TabPage tp = HoverTab();

            if (tp != null)
            {
                if (!r.Contains(e.X, e.Y))
                    DoDragDrop(tp, DragDropEffects.All);
            }
            DragStartPosition = Point.Empty;
        }

        private void SwapTabPages(TabPage tp1, TabPage tp2)
        {
            int Index1 = this.TabPages.IndexOf(tp1);
            int Index2 = this.TabPages.IndexOf(tp2);
            this.TabPages[Index1] = tp2;
            this.TabPages[Index2] = tp1;
        }
    }
}
使用系统;
使用System.Collections.Generic;
使用系统组件模型;
使用系统数据;
使用系统图;
使用System.Linq;
使用系统文本;
使用System.Windows.Forms;
使用可重复性。属性;
命名空间为sole.Core
{
/// 
///在现有TabControl上实现选项卡页所需的所有额外功能。
///包括DrawItem、MouseMove和MouseDown的事件。
/// 
公共部分类ExtendedTabControl:TabControl
{
/// 
///初始化ExtendedTabControl类的新实例。将添加所有事件。
/// 
public ExtendedTabControl():base()
{
this.DrawItem+=新的DrawItemEventHandler(DrawTab);
this.MouseClick+=新的MouseEventHandler(Tab_OnMouseDown);
this.MouseMove+=新的MouseEventHandler(MouseMove上的标签);
this.DragOver+=新的DragEventHandler(Tab_OnDragOver);
}
/// 
///用于存储选项卡拖动事件的起始位置。
/// 
专用点DragStartPosition=点.空;
private void DrawTab(对象发送方,DrawItemEventArgs e)
{
//
//此代码将呈现选项卡标题末尾的关闭按钮。
//
e、 Graphics.DrawImage(Resources.TabCloseButton,e.Bounds.Right-22,e.Bounds.Top+5,14,14);
e、 Graphics.DrawString(this.TabPages[e.Index].Text、e.Font、brush.Black、e.Bounds.Left+12、e.Bounds.Top+3);
e、 DrawFocusRectangle();
}
MouseDown上的私有无效选项卡(对象发送者,System.Windows.Forms.MouseEventArgs e)
{
//
//无论MouseDown事件起源于何处,保存坐标以进行拖动。
//
DragStartPosition=新点(e.X,e.Y);
#区域关闭按钮处理
//
//关闭按钮代码-通过控件循环。
//
for(int i=0;i对于(int index=0;index好吧,因为似乎没有人知道解决方案,经过过多的测试和调整,再加上一些非常幸运的发现,我很高兴地报告,通过替换
GetPresentData
GetData
调用,这个问题很容易解决。我为
选项卡提供了调整后的代码_OnDragOver
这就是问题的根源,我希望对于点击此页面并寻找解决方案的任何人来说,这一切都能正常工作

private void Tab_OnDragOver(object sender, System.Windows.Forms.DragEventArgs e)
        {
            TabPage hover_Tab = HoverTab();
            if (hover_Tab == null)
                e.Effect = DragDropEffects.None;
            else
            {
                var drag_tab = e.Data.GetData(e.Data.GetFormats()[0]);
                if (typeof(TabPage).IsAssignableFrom(drag_tab.GetType()))
                {
                    e.Effect = DragDropEffects.Move;

                    if (hover_Tab == drag_tab) return;

                    Rectangle TabRect = GetTabRect(TabPages.IndexOf(hover_Tab));
                    TabRect.Inflate(-3, -3);
                    if (TabRect.Contains(PointToClient(new Point(e.X, e.Y))))
                    {
                        SwapTabPages(drag_tab as TabPage, hover_Tab);
                        SelectedTab = drag_tab as TabPage;
                    }
                }
            }
        }

我看不出你的代码有什么问题。你是否尝试过跟踪?如果你在
SwapTabPages()上设置断点
它被击中了吗?我尝试了一些使用我的类而不是TabPage的修改,它似乎起了作用。问题出在GetDataPresent和GetData部分的某个地方的Tab_OnMouseMove部分,因为
typeof
语句。但我不确定如何更改代码以使它起作用!@shamp00实际上我的坏消息在OnDragOver事件中!