c#.NET 2.0缩放滚动条
我正在寻找一个控件,允许用户缩放和滚动在同一时间。它基本上需要像Sony Sound Forge一样,请参见此屏幕截图的底部: 它的外观和行为类似于普通滚动条,此外,您还可以左右拖动边缘,使图表放大/缩小。即使向用户提供了放大和滚动的替代方法(例如,通过拖动图表上的某个区域),我仍然认为这样的组件是有用的,因为它为用户提供了数据中位置和已应用缩放量的直接视觉反馈c#.NET 2.0缩放滚动条,c#,scroll,c#-2.0,zooming,charts,C#,Scroll,C# 2.0,Zooming,Charts,我正在寻找一个控件,允许用户缩放和滚动在同一时间。它基本上需要像Sony Sound Forge一样,请参见此屏幕截图的底部: 它的外观和行为类似于普通滚动条,此外,您还可以左右拖动边缘,使图表放大/缩小。即使向用户提供了放大和滚动的替代方法(例如,通过拖动图表上的某个区域),我仍然认为这样的组件是有用的,因为它为用户提供了数据中位置和已应用缩放量的直接视觉反馈 这样的组件是否存在,或者我是否需要自己创建它?欢迎任何帮助。我认为这是非常具体的控制,我不认为它存在。另外,我认为自己创建它会比搜索
这样的组件是否存在,或者我是否需要自己创建它?欢迎任何帮助。我认为这是非常具体的控制,我不认为它存在。另外,我认为自己创建它会比搜索它或等待别人回答这个问题更快 要绘制类似Sound Forge中的自定义按钮,可以使用WinAPI函数
DrawThemeBackground
我举几个简短的例子:
public partial class Form1 : Form
{
readonly Int32 ScrollBarWidth;
readonly Int32 ScrollBarHeight;
public Form1()
{
InitializeComponent();
ScrollBarWidth = GetSystemMetrics(SM_CYVSCROLL);
ScrollBarHeight = GetSystemMetrics(SM_CYHSCROLL);
}
private void panel1_Paint(object sender, PaintEventArgs e)
{
Int32 ZoomMarkerSize = 6;
Graphics G = e.Graphics;
Int32 SBWidth = ScrollBarWidth;
Int32 SBHeight = ScrollBarHeight;
DrawCustomScrollButton(G, 0, 0, SBWidth, SBHeight, Resources.Plus,
(int) SCROLLBARSTYLESTATES.SCRBS_NORMAL);
DrawCustomScrollButton(G, SBWidth, 0, ZoomMarkerSize, SBHeight, null,
(int) SCROLLBARSTYLESTATES.SCRBS_NORMAL);
DrawCustomScrollButton(G, SBWidth + ZoomMarkerSize, 0, SBWidth, SBHeight, Resources.Minus,
(int) SCROLLBARSTYLESTATES.SCRBS_HOT);
}
public void DrawCustomScrollButton (Graphics aG, Int32 aX, Int32 aY, Int32 aWidth, Int32 aHeight,
Image aImage, Int32 aState)
{
RECT R = new RECT () { left = aX, top = aY, right = aX + aWidth, bottom = aY + aHeight };
RECT NotUsed = R;
IntPtr ThemeHandle = OpenThemeData(this.Handle, "SCROLLBAR");
IntPtr HDC = aG.GetHdc();
DrawThemeBackground
(
ThemeHandle, HDC,
(int) SCROLLBARPARTS.SBP_THUMBBTNHORZ,
aState,
ref R, ref NotUsed
);
aG.ReleaseHdc(HDC);
CloseThemeData(ThemeHandle);
if (aImage != null)
{
aG.DrawImage(aImage,
aX + ((ScrollBarHeight - aImage.Width ) / 2),
aY + ((ScrollBarHeight - aImage.Height ) / 2));
}
}
public struct RECT
{
public Int32 left;
public Int32 top;
public Int32 right;
public Int32 bottom;
}
[DllImport("user32.dll")]
public static extern int GetSystemMetrics(int smIndex);
[DllImport("uxtheme.dll", ExactSpelling=true)]
public extern static Int32 DrawThemeBackground(IntPtr hTheme, IntPtr hdc, int iPartId,
int iStateId, ref RECT pRect, ref RECT pClipRect);
[DllImport("uxtheme.dll", ExactSpelling=true, CharSet=CharSet.Unicode)]
public static extern IntPtr OpenThemeData(IntPtr hWnd, String classList);
[DllImport("uxtheme.dll", ExactSpelling=true)]
public extern static Int32 CloseThemeData(IntPtr hTheme);
public int SM_CYHSCROLL = 3;
public int SM_CYVSCROLL = 20;
public int SBP_ARROWBTN = 1;
public int ABS_UPNORMAL = 1;
public int ABS_UPHOT = 2;
public int ABS_UPHOVER = 17;
public enum ARROWBTNSTATES {
ABS_UPNORMAL = 1,
ABS_UPHOT = 2,
ABS_UPPRESSED = 3,
ABS_UPDISABLED = 4,
ABS_DOWNNORMAL = 5,
ABS_DOWNHOT = 6,
ABS_DOWNPRESSED = 7,
ABS_DOWNDISABLED = 8,
ABS_LEFTNORMAL = 9,
ABS_LEFTHOT = 10,
ABS_LEFTPRESSED = 11,
ABS_LEFTDISABLED = 12,
ABS_RIGHTNORMAL = 13,
ABS_RIGHTHOT = 14,
ABS_RIGHTPRESSED = 15,
ABS_RIGHTDISABLED = 16,
ABS_UPHOVER = 17,
ABS_DOWNHOVER = 18,
ABS_LEFTHOVER = 19,
ABS_RIGHTHOVER = 20,
};
public enum SCROLLBARSTYLESTATES {
SCRBS_NORMAL = 1,
SCRBS_HOT = 2,
SCRBS_PRESSED = 3,
SCRBS_DISABLED = 4,
SCRBS_HOVER = 5,
};
public enum SCROLLBARPARTS {
SBP_ARROWBTN = 1,
SBP_THUMBBTNHORZ = 2,
SBP_THUMBBTNVERT = 3,
SBP_LOWERTRACKHORZ = 4,
SBP_UPPERTRACKHORZ = 5,
SBP_LOWERTRACKVERT = 6,
SBP_UPPERTRACKVERT = 7,
SBP_GRIPPERHORZ = 8,
SBP_GRIPPERVERT = 9,
SBP_SIZEBOX = 10,
};
}
以下是用于参考资料的表单源文件和两个测试PNG图像:有关此API和PINVOKE.NET站点的函数签名的更多信息,请查看MSDN 编辑
更好的解决方案是使用
VisualStyleRenderer
类。对不起,第一个复杂的例子。我以前不知道那门课。因此,我的DrawCustomScrollButton
功能应该被替换:
public void DrawCustomScrollButton (Graphics aG, Int32 aX, Int32 aY, Int32 aWidth, Int32 aHeight,
Image aImage, Int32 aState)
{
Rectangle R = new Rectangle(aX, aY, aX + aWidth, aY + aHeight);
VisualStyleRenderer Renderer = new VisualStyleRenderer
(
VisualStyleElement.ScrollBar.ThumbButtonHorizontal.Normal
);
Renderer.DrawBackground(aG, R);
if (aImage != null)
{
aG.DrawImage(aImage,
aX + ((ScrollBarHeight - aImage.Width ) / 2),
aY + ((ScrollBarHeight - aImage.Height ) / 2));
}
}
编辑2
考虑到您的评论,我尝试重新创建此自定义控件。主要想法是使用standart滚动条,并在其上方放置缩放标记(两个面板控件)。乍一看很容易。但要将这些组件组合在一起比我想象的要困难得多
主要问题是很难改变系统滚动条控件的行为。我发现它不允许处理我想要覆盖的windows消息队列中的某些事件。例如MouseUp事件和其他一些事件
最后,我认为唯一正确的方法是从头开始重新创建自己的ScrollBar控件副本,在该副本中不会有这些约束。正因为如此,起初我走错了路,不幸的是没有解决你的任务
无论如何,这里是我当前的结果(完整解决方案):
您在该容器中使用了哪些控件?我打算使用图形显示,与上面的屏幕截图非常相似。这回答了你的问题吗?因为我认为这不相关。例如,每次用户缩放或滚动时,缩放滚动条必须给出2个介于0和1之间的浮点值。这些值表示钢筋的起点和终点位置。(上面的屏幕是Sony Sound Forge,Sony的音频编辑工具,不是我自己的软件)我认为你可以通过你的组件解决这个问题,我认为每次变焦你都必须放大你的精度。@lazycider:我不认为我们在这方面有相同的想法,至少我根本不理解你的答案。我正在寻找一个UI控件,如屏幕截图中的一个。这种控制背后的逻辑当然不是火箭科学。正如我在上面描述的,每次用户操作控件时,它应该只返回2个值。我只是想知道是否存在这样一个UI组件。我当然可以自己创建一个,但要使它具有一致的Windows外观和感觉,这将是一项相当大的工作。我不介意+和-按钮。事实上,我会很高兴有两个按钮只是+和-作为文本放在他们。它们可以与滚动条集成到customcontrol中。但这不是主要问题。主要问题是滚动条本身,它必须允许用户允许缩放和滚动。滚动可以像任何普通的滚动条一样进行,缩放可以通过拖动一条横杆(或者称为“拇指”)来做,或者离杆的另一边更近或者更近。如果你仔细看这个例子,你会发现,在每边上有2个夹子,而不是像中间的一个普通滚动条那样。在过去,我使用了这个程序的旧版本,不完全理解你的问题。遗憾的是,你没有在截图上标出你需要的东西。今天我还安装了Sound Forge的试用版,并看到了新的滚动条是如何工作的。所以,等我有时间的时候,我会尽量为你的问题找到更正确的答案。如果我会成功,我会更新。今天我做了一个新的例子,但它没有完成,并且有一些错误。如果你想在这里看到我目前的结果,我的解决方案是:Dmitry,它看起来绝对棒极了,这正是我想要的。