【问题标题】:Refresh the panels of a SplitContainer as the splitter moves拆分器移动时刷新 SplitContainer 的面板
【发布时间】:2011-06-29 13:51:08
【问题描述】:

我有一个带有两个面板的 SplitContainer。当我拖动拆分器以调整两个面板的大小时,我在拖动时看到一个灰色条。在我释放鼠标按钮之前,面板实际上并没有被重绘。如何使面板刷新我拖动拆分器?

Fwiw,这是在 Delphi 中通过将 Splitter 控件的“ResizeStyle”设置为“rsUpdate”来实现的。

我已尝试将以下代码放入 SplitterMoving 事件中,但没有可见的更改。

private void splitCont_SplitterMoving(object sender, SplitterCancelEventArgs e)
{
    splitCont.Invalidate();
    //also tried this:
    //splitCont.Refresh();
}

【问题讨论】:

    标签: c# winforms


    【解决方案1】:

    您可以尝试使用鼠标事件,详细in this page:

        //assign this to the SplitContainer's MouseDown event
        private void splitCont_MouseDown(object sender, MouseEventArgs e)
        {
            // This disables the normal move behavior
            ((SplitContainer)sender).IsSplitterFixed = true;
        }
    
        //assign this to the SplitContainer's MouseUp event
        private void splitCont_MouseUp(object sender, MouseEventArgs e)
        {
            // This allows the splitter to be moved normally again
            ((SplitContainer)sender).IsSplitterFixed = false;
        }
    
        //assign this to the SplitContainer's MouseMove event
        private void splitCont_MouseMove(object sender, MouseEventArgs e)
        {
            // Check to make sure the splitter won't be updated by the
            // normal move behavior also
            if (((SplitContainer)sender).IsSplitterFixed)
            {
                // Make sure that the button used to move the splitter
                // is the left mouse button
                if (e.Button.Equals(MouseButtons.Left))
                {
                    // Checks to see if the splitter is aligned Vertically
                    if (((SplitContainer)sender).Orientation.Equals(Orientation.Vertical))
                    {
                        // Only move the splitter if the mouse is within
                        // the appropriate bounds
                        if (e.X > 0 && e.X < ((SplitContainer)sender).Width)
                        {
                            // Move the splitter & force a visual refresh
                            ((SplitContainer)sender).SplitterDistance = e.X;
                            ((SplitContainer)sender).Refresh();
                        }
                    }
                    // If it isn't aligned vertically then it must be
                    // horizontal
                    else
                    {
                        // Only move the splitter if the mouse is within
                        // the appropriate bounds
                        if (e.Y > 0 && e.Y < ((SplitContainer)sender).Height)
                        {
                            // Move the splitter & force a visual refresh
                            ((SplitContainer)sender).SplitterDistance = e.Y;
                            ((SplitContainer)sender).Refresh();
                        }
                    }
                }
                // If a button other than left is pressed or no button
                // at all
                else
                {
                    // This allows the splitter to be moved normally again
                    ((SplitContainer)sender).IsSplitterFixed = false;
                }
            }
        }
    

    【讨论】:

    • 这成功了!作为参考,我将编辑您的答案以包含实际代码。谢谢!
    • 我这样做了,但为了可重用性,我将SplitContainer 子类化(并使用Invalidate() 而不是Refresh())。谢谢!
    • 这个答案仍然像一个魅力。更具吸引力的分离器运动。
    • 我要补充一点,将Refresh 替换为Invalidate 会引入大量闪烁,因此请谨慎选择。
    • 是的@DonBoitnott,确实如此。 Invalidate 只会在您停止移动分离器时“刷新”面板,当您停止移动时...Refresh 将为每次移动、每个像素刷新面板。但这对依赖于Paint 事件的控件产生了不良影响,因为对它们来说,这将是一种难看的闪烁效果。例如,我在两个面板上添加了一条渐变线,并在每个面板上添加了一个FlowLayoutPanel。流式布局使用这种方法可以正常工作,但是它会在鼠标的每次移动时重新绘制渐变线,这会导致闪烁效果......
    猜你喜欢
    • 2012-07-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多