我的回收站

技术文章、随笔、文摘及其它
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理
这两天想做一个PPC上的小程序,才发现它上面很多东西做起来好麻烦。。。。
就拿滚动窗体里面的内容来说,在普通的WinForm下是很容易的,这里都得要自己实现。
终于在微软的示例中找到一个例子 ,不过发现窗体上如果有输入面板控件的话,如果输入法面板显示出来则会遮盖住窗体的一部分,那么就会比较麻烦。一直找不到好的解决方案,经过一番折腾,终于算是搞妥了这个问题,现将解决思路写出来,大家看看有没有什么优化的地方。

首先:窗体中所有要显示的控件都应该放到一个Panel里面,其次在窗体上放上一个VScrollBar,当然如果你也需要横向滚动条那么也放上一个吧,如下图所示:

Panel的宽度设置为224,高度根据里面的内容来具体确定。滚动条的宽度设置为16,高度为320。
        private void Form1_Load(object sender, System.EventArgs e)
        
{
            
this.vScrollBar1.Maximum =this.panel1.Height -this.Height;
        }

也就是说,假如Panel的高度为400,那么滚动条的需要表示的最大值只需要是面板的高度减去窗体的高度就行了。

其次,增加如下代码:
        private int preValue;
        
private void vScrollBar1_ValueChanged(object sender, System.EventArgs e)
        
{
            
//只有当输入面板是打开的时候,
            
//并且不是Panel中最上面的控件(这里我采用了硬编码,大家其实完全也可以通过程序遍历来实现,但是似乎没有必要费这劲)
            
//而且只有用户是往下滚动窗体的时候需要处理
            if(this.inputPanel1.Enabled && (!sender.Equals(this.textBox1))  && this.vScrollBar1.Value >=this.preValue)
                
//面板的Top实际上设置为滚动条的值再加上输入面板的高度的和的复制,也就是把Panel往上移动就相当于滚动了
                this.panel1.Top =-(this.vScrollBar1.Value + this.inputPanel1.Bounds.Height);
            
else
                
//否则的话,只需要把Panel往上移动滚动条的值的大小就行了
                this.panel1.Top =-this.vScrollBar1.Value;
            
//记录当前值
            this.preValue =this.vScrollBar1.Value;
        }

        
private void inputPanel1_EnabledChanged(object sender, System.EventArgs e)
        
{
            
if(this.inputPanel1.Enabled)
                
this.vScrollBar1.Height =this.inputPanel1.VisibleDesktop.Height;
            
else
                
this.vScrollBar1.Height =this.ClientSize.Height;
        }

        
private void ShowInputPanel(object sender,System.EventArgs e)
        
{
            
this.inputPanel1.Enabled =true;
            SetScrollBar(sender);
        }

        
private void HideInputPanel(object sender,System.EventArgs e)
        
{
            
//如果输入法面板上一次也是隐藏的,这次就不用动了,直接返回吧。
            if(!this.inputPanel1.Enabled)
                
return;
            
this.inputPanel1.Enabled=false;
            SetScrollBar(sender);
        }

        
private void SetScrollBar(object sender)
        
{
            Control c
=(Control)sender;
            
//根据当前控件计算滚动条应该设置的值,然后再次触发滚动条的ValueChanged事件来调整滚动条
            this.vScrollBar1.Value =this.vScrollBar1.Maximum*c.Top/this.panel1.Height ;
            
this.vScrollBar1_ValueChanged(sender,null);
        }



最后,将所有需要显示输入法面板的控件如下处理,使其获得焦点的时候可以显示输入法面板并且调整窗体中控件位置:
this.textBox1.GotFocus += new System.EventHandler(this.ShowInputPanel);

所有要隐藏输入法面板的控件再作如下处理,使其获得焦点的时候隐藏输入法面板并且调整控件位置:
this.radioButton1.GotFocus += new System.EventHandler(this.HideInputPanel);

OK,经过如上处理之后,您的窗体中的控件位置首先会随着滚动条的位置的改变而滚动。
其次,当弹出或者隐藏输入法面板的时候,位置也会随之相应调整。