重构代码以使用自定义类而不是系统提供的类
本文关键字:系统 自定义 重构 代码 | 更新日期: 2023-09-27 18:18:50
好吧,这可能是最愚蠢的问题,但我有一个大问题困扰着我。首先,我使用了Mick Doherty在运行时重新定位TabItems下的选项卡控制提示中的代码示例,以允许在控件中拖放选项卡。问题是我使用一个自定义TabPage类的名称为ExtendedTabPage
,这给我带来了麻烦。我尝试过铸造或使用as
关键字,但我运气不好,所以我希望有人帮助我如何重构代码,以允许拖动自定义选项卡。
EDIT:我忘了提到ExtendedTabPage是一个抽象类,由我的对象继承(例如,我的一个Windows属于继承ExtendedTabPage的ConsoleTab类)。这和问题本身有关系吗?
EDIT 2:主要发现-在DragOver方法中,如果我尝试在语句的类型中使用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;
}
}
}
现在忽略任何额外的东西,我把整个代码给你,以防其他任何东西把它弄乱。综上所述,我希望有人能够修复代码,或者至少解释如何这样做(或者如果不可能做什么),以便我能够在ExtendedTabPage项之间交换,而不是常规的TabPage。我已经尝试过了,常规的TabPage对象可以工作,而我的自定义对象则不行。如果解决方案必须只包括其中一个(所以普通tabpage不能工作),只去ExtendedTabPage,因为我可以将其余的东西转换成它。我希望这不是真的很愚蠢,也不是我忽视了什么。
p。S:我还检查了我链接的页面,以寻找适用于自定义类的解决方案,但没有运气,因为它给我带来了两倍的问题,一半的代码甚至与适当的汇编引用一起崩溃,所以这不是一个真正的选择。:/
嗯,由于似乎没有人知道解决方案,经过过度的测试和调整加上一些非常幸运的发现在网站上,即如何处理getdatpresentent让它接受所有派生类型和c#拖放- e.Data.GetData使用基类,我很高兴地报告,这个问题可以很容易地通过替换GetPresentData
和GetData
调用来解决。我提供了Tab_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;
}
}
}
}