3

设想

我需要使用KryptonSeparator的帮助。

我想使用下图中的分隔符来调整左右控件的宽度:

在此处输入图像描述

问题

问题是当我尝试将分隔符向左移动时,它会产生非常令人不安的视觉效果,当我将分隔符向右移动时或多或少会发生相同的事情,但向左移动更明显(而且可怕):

在此处输入图像描述

我认为我没有正确使用事件参数,KryptonSeparator因为当我将分隔符向左移动时,我使用分隔符的宽度而不是事件数据进行计算(因为我不知道如何正确执行)。

问题

我应该在我的代码中做哪些修改来解决调整大小的问题?

代码

左右控件都分配了一个属性,如果达到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)
//=======================================================

更新

我更新了上面的代码以简化阅读,我正在分享这个新视频,您可以在其中看到设计问题:

www.youtube.com/watch?v=-MhmyE3MZX0

4

1 回答 1

3

首先,您需要获取用户在拖动之前单击的位置,mouse down event of splitter control以及total width三个控件:

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

您调整两个窗口大小的逻辑有两个小错误:

  1. 使用e.MouseCursorX来确定调整大小的方向(左或右)是错误的,例如,您将光标移到左(左方向),保留在分隔符内,e.MouseCursorX仍然是正数,所以您要向右调整大小(当然直到 e .MouseCursorX 变为负数)而不是
  2. 您的代码检查最小大小,但当比较为false时不执行任何操作,这意味着当控件的结果大小较小时。发生这种情况时,您需要实际设置控件的大小,例如,最小大小为50,控件大小为55。如果调整大小非常快,则控件的最终大小可能会变为49。您的代码什么都不做(比较为假),控件的大小保持为55而不是将其设置为50

我的解决方案解决了这两种情况。但是,您所说的可怕效果的真正问题不是这两个错误。实际上,当您调整控件大小时,应用程序的响应速度太慢了。更具体地说,当您调整大小移动右侧control(ListBox_Files)时。如果您拖放少量(1 或 2 个)文件并查看结果,您可以自行检查。这是一个巨大的差异。不幸的是,这告诉我您对此无能为力。您需要更改调整大小的逻辑。两种解决方案:

  1. 使用一个控件并自定义绘制所有内容、文本、图标、垂直水平滚动条等。(不推荐!)
  2. 做视觉工作室和其他应用程序正在做的事情。在释放按钮之前不要调整控件的大小。只显示一条垂直线:

在此处输入图像描述

在此处输入图像描述

于 2014-12-01T17:54:29.173 回答