Scenario
我需要使用 KryptonSeparator 的帮助.
我想使用下图中的分隔符来调整左右控件的宽度:
Problem
问题是,当我尝试将分隔符向左移动时,它会产生非常令人不安的视觉效果,而当我将分隔符向右移动时,或多或少会发生同样的事情,但向左移动要明显得多(和可怕的):
我认为我没有正确使用 KryptonSeparator
的事件参数,因为当我将分隔符向左移动时,我是基于使用分隔符的宽度而不是事件数据进行计算(因为我不知道如何正确地做到这一点)。
Question
我应该在我的代码中做哪些修改来解决大小调整问题?
Code
左右控件都分配了 MinimumSize
属性,如果达到 MinimumSize.Width
,我将尝试停止调整大小。
这是源代码,在 VB.Net 中:
''' <summary>
''' Handles the SplitterMoving event of the KryptonSeparator1 control.
''' </summary>
Private Sub KryptonSeparator1_SplitterMoving(ByVal sender As Object, ByVal e As SplitterCancelEventArgs) _
Handles KryptonSeparator1.SplitterMoving
Dim separator As KryptonSeparator = DirectCast(sender, KryptonSeparator)
Dim leftCtrl As Control = Control1
Dim rightCtrl As Control = Control2
If (e.MouseCursorX > 0) _
AndAlso Not ((rightCtrl.Size.Width - e.MouseCursorX) < rightCtrl.MinimumSize.Width) Then
separator.Location = New Point(separator.Location.X + e.MouseCursorX, separator.Location.Y)
leftCtrl.Width += e.MouseCursorX
rightCtrl.Width -= e.MouseCursorX
rightCtrl.Left = separator.Right
ElseIf (e.MouseCursorX < 0) _
AndAlso Not ((leftCtrl.Size.Width + e.MouseCursorX - separator.Width) < leftCtrl.MinimumSize.Width) Then
separator.Location = New Point(separator.Location.X - separator.Width, separator.Location.Y)
leftCtrl.Width -= separator.Width
rightCtrl.Width += separator.Width
rightCtrl.Left = separator.Right
End If
End Sub
这是源代码,在 C# 中:
/// Handles the SplitterMoving event of the KryptonSeparator1 control.
/// </summary>
private void KryptonSeparator1_SplitterMoving(object sender, SplitterCancelEventArgs e)
{
KryptonSeparator separator = (KryptonSeparator)sender;
FolderView leftCtrl = this.FolderView_Files;
KryptonListBox rightCtrl = this.KryptonListBox_Files;
if ((e.MouseCursorX > 0) && !((rightCtrl.Size.Width - e.MouseCursorX) < rightCtrl.MinimumSize.Width)) {
separator.Location = new Point(separator.Location.X + e.MouseCursorX, separator.Location.Y);
leftCtrl.Width += e.MouseCursorX;
rightCtrl.Width -= e.MouseCursorX;
rightCtrl.Left = separator.Right;
} else if ((e.MouseCursorX < 0) && !((leftCtrl.Size.Width + e.MouseCursorX - separator.Width) < leftCtrl.MinimumSize.Width)) {
separator.Location = new Point(separator.Location.X - separator.Width, separator.Location.Y);
leftCtrl.Width -= separator.Width;
rightCtrl.Width += separator.Width;
rightCtrl.Left = separator.Right;
}
}
//=======================================================
//Service provided by Telerik (www.telerik.com)
//=======================================================
UPDATE
我更新了上面的代码以简化阅读,我正在分享这个新视频,您可以在其中看到设计问题:
最佳答案
首先需要获取拖动前用户点击的位置,拆分控件的鼠标按下事件
和三个控件的总宽度
:
Private mouse_Down As Point //you can use an integer also because y coordinate remains the same
Private totalWidth As Integer
//mouse down event
mouse_Down.X = e.MouseCursorX
totalWidth = seperator.Width + LeftControl.Width + RightControl.Width
Private Sub KryptonSeparator1_SplitterMoving(ByVal sender As Object, ByVal e As SplitterCancelEventArgs) Handles KryptonSeparator1.SplitterMoving
Dim separator As KryptonSeparator = DirectCast(sender, KryptonSeparator)
Dim leftCtrl As Control = Control1
Dim rightCtrl As Control = Control2
Dim leftWidth, rightWidth As Integer
leftWidth = leftCtrl.Width + (e.MouseCursorX - mouse_Down.X)
rightWidth = rightCtrl.Width - (e.MouseCursorX - mouse_Down.X)
If leftWidth <= leftCtrl.MinimumSize.Width Then
leftCtrl.Width = leftCtrl.MinimumSize.Width
separator.Left = leftCtrl.Left + leftCtrl.MinimumSize.Width
rightCtrl.Left = leftCtrl.Left + leftCtrl.MinimumSize.Width + separator.Width
rightCtrl.Width = totalWidth - leftCtrl.MinimumSize.Width - separator.Width
Return
End If
If rightWidth <= rightCtrl.MinimumSize.Width Then
leftCtrl.Width = totalWidth - rightCtrl.MinimumSize.Width - separator.Width
separator.Left = leftCtrl.Left + leftCtrl.Width
rightCtrl.Left = leftCtrl.Left + leftCtrl.Width + separator.Width
rightCtrl.Width = rightCtrl.MinimumSize.Width
Return
End If
separator.Left += (e.MouseCursorX - mouse_Down.X)
leftCtrl.Width = leftWidth
rightCtrl.Width = rightWidth
rightCtrl.Left = leftCtrl.Left + leftWidth + separator.Width
End Sub
编辑
试试这个:
//mouse down event
//mouse_Down.X = e.MouseCursorX
mouse_Down.X = MousePosition.X
mouse_Down.Y = MousePosition.Y
mouse_Down = seperator.PointToClient(mouse_Down)
totalWidth = seperator.Width + LeftControl.Width + RightControl.Width
在 SplitterMoving
中:
Dim leftWidth, rightWidth As Integer
Dim pnt As Point
pnt.X = MousePosition.X
pnt.Y = MousePosition.Y
pnt = seperator.PointToClient(pnt)
//replace e.MouseCursorX with pnt.X
...
编辑 2
调整两个窗口大小的逻辑有两个小错误:
- 使用
e.MouseCursorX
确定调整大小的方向(左或右)是错误的,例如您将光标移动到左(左方向) ), 保留在分隔符内,e.MouseCursorX
仍然是正数,因此您正在向右侧调整大小(当然直到 e.MouseCursorX 变为负数) 而不是离开! - 您的代码会检查最小大小,但当比较结果为 false 时不执行任何操作,这意味着控件的结果大小较小。 当发生这种情况时,您需要实际设置控件的大小例如 假设最小大小为50,而控件大小为55。如果调整大小非常快,则控件的最终大小可能会变为 49。你的代码什么都不做(比较是错误的)和大小 控件保持 55 而不是将其设置为 50。
我的解决方案解决了这两种情况。但是,您所说的糟糕效果的真正问题不是这两个错误。其实是, 当您调整控件大小时,应用程序的响应速度太慢。更具体地说,当您向右调整和移动 控件(ListBox_Files)。如果您拖放少量(1 或 2)个文件并查看结果,您可以自行检查。这是一个巨大的 不同之处。不幸的是,这告诉我你对此无能为力。您需要更改调整大小的逻辑。两种解决方案:
- 使用一个控件并自定义绘制所有内容、文本、图标、垂直-水平滚动条等。(不推荐!)
- 做 visual studio 和其他应用程序正在做的事情。在释放按钮之前不要调整控件的大小。只显示一条垂直线:
关于c# - KryptonSeparator 调整大小问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27163071/