Visual C# .Net環境中編程實現浮動工具列

來源:互聯網
上載者:User
  DotNet2.0開發架構中提供的ToolStrip和ToolStripPanel控制項可以方便開發具有可停駐工具列功能的Windows應用程式, ToolStrip對象可以在各個ToolStripPanel間完成拖拽停靠,但是如果想實作類別似VS IDE 或Office中可以浮動的工具列必須藉助於DevExpress等一些第三方的控制項或編寫一定的代碼。 這裡介紹一種比較簡單的方法,只需繼承ToolStrip類即可實現上述的效果。

  放置到ToolStripPanel上的,當工具列浮動的時候,事實上是改變了其所在的容器物件,從其所在的ToolStripPanel移動到一個漂浮的容器上,因此要實現工具列的浮動必須解決以下兩個問題:

    必須有一個浮動的容器來承載ToolStrip對象。
    須知道ToolStrip對象何時改變其所在的容器,即在浮動的容器和主視窗上ToolStripPanel之間停靠。

  對於第一個問題,我們的解決方案是動態建立一個Form類作為浮動的容器,命名為ToolStripFloatWindow,該Form對象具有以下的屬性:

    FormBorderStyle = FixedToolWindow 邊框樣式
    ShowInTaskbar = false 不在工作列顯示
    ShowIcon = false 不顯示視窗表徵圖
    TopMost = true 在所有視窗之上

  為瞭解決第二個問題,我們查閱MSDN獲知,當用滑鼠拖拽ToolStrip對象釋放滑鼠時會觸發其EndDrag事件。 我們在這個事件的處理方法中判斷當ToolStrip對象的位置被移動到所在的ToolStripPanel之外的時候,建立ToolStripFloatWindow對象,並將ToolStrip對象移動到ToolStripFloatWindow上;要使ToolStrip對象恢複到原來的表單上只要判斷ToolStripFloatWindow對象的位置是否移動到了ToolStripPanel上, 當條件滿足時將ToolStrip對象移動回ToolStripPanel中並銷毀ToolStripFloatWindow對象。

  此外,還要解決當ToolStrip對象放置到ToolStripFloatWindow對象上時, ToolStripFloatWindow對象必須與ToolStrip對象的尺寸一致。 還有ToolStripFloatWindow對象被點擊了關閉按鈕時不能將自己關閉。我們可以做兩個類來實現上述的思路。

ToolStripFloatWindow類繼承自Form類。
MyToolStrip 繼承自ToolStrip類。增加了相應的屬性和方法。

MyToolStrip類的原始碼如下:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace FloatingToolStrip
...{
public partial class MyToolStrip : ToolStrip
...{
public MyToolStrip()
...{
InitializeComponent();
this.EndDrag += new EventHandler(MyToolStrip_EndDrag);
this.SizeChanged += new EventHandler(MyToolStrip_SizeChanged);
}

protected override void OnPaint(PaintEventArgs pe)
...{
// TODO: 在此處添加自訂繪製代碼

// 調用基類 OnPaint
base.OnPaint(pe);
}

  漂浮狀態#region 漂浮狀態

private ToolStripFloatWindow floatWindow;

public ToolStripFloatWindow FloatWindow
...{
get
...{
return this.floatWindow;
}
set
...{
floatWindow = value;
if (FloatWindow != null)
...{
floatWindow.LocationChanged += new EventHandler(floatWindow_LocationChanged);
floatWindow.FormClosing += new FormClosingEventHandler(floatWindow_FormClosing);
}
}
}

public bool isFloating
...{
get
...{
return (floatWindow != null);
}
}

private ToolStripPanel tsPanel;

public ToolStripPanel ToolStripPanel
...{
get
...{
return this.tsPanel;
}
set
...{
tsPanel = value;
}
}

#endregion

  漂浮實現#region 漂浮實現

private void floatWindow_LocationChanged(object sender, EventArgs e)
...{
//當floatwindws的位置移動到 toolstrippanel中時,將this放置到 toolstripPanel上
if (this.floatWindow == null)
...{
return;
}
Point currentPt = new Point(floatWindow.Location.X, floatWindow.Location.Y);
Point minpt = this.tsPanel.PointToScreen(tsPanel.Location);
Point maxpt;
if(this.tsPanel.Height <= 20)...{
maxpt = new Point(minpt.X + this.tsPanel.Width, minpt.Y + 20);
}else...{
maxpt = new Point(minpt.X + this.tsPanel.Width, minpt.Y + this.tsPanel.Height);
}

if ((currentPt.X > minpt.X) && (currentPt.X < maxpt.X) && (currentPt.Y > minpt.Y) && (currentPt.Y < maxpt.Y))
...{
this.floatWindow.Controls.Remove(this);
this.tsPanel.SuspendLayout();
this.tsPanel.Controls.Add(this);
this.Location = this.tsPanel.PointToClient(currentPt);
this.tsPanel.ResumeLayout();
this.floatWindow.Dispose();
this.floatWindow = null;

}
}

private void MyToolStrip_EndDrag(object sender, EventArgs e)
...{
//判斷移出時
if (this.tsPanel == null)
...{
MessageBox.Show("請先設定ToolStripPanel屬性");
return;
}
Point endPoint = Cursor.Position;
int openX, openY;
openX = endPoint.X;
openY = endPoint.Y;
Point clientPt = this.tsPanel.Parent.PointToClient(endPoint);
if (clientPt.Y > tsPanel.Height)
...{
ToolStripFloatWindow fw = new ToolStripFloatWindow();
this.tsPanel.Controls.Remove(this);
fw.Controls.Add(this);
this.Left = 0;
this.Top = 0;
this.FloatWindow = fw;
Point newLoc = new Point(openX, openY);
fw.Show();
fw.Location = newLoc;
fw.SetBounds(newLoc.X, newLoc.Y, this.ClientSize.Width, this.ClientSize.Height);
}
}

private void floatWindow_FormClosing(object sender, FormClosingEventArgs e)
...{
e.Cancel = true;
}

private void MyToolStrip_SizeChanged(object sender, EventArgs e)
...{
if (this.isFloating)
...{
this.floatWindow.Width = this.ClientSize.Width;
}
}

#endregion

}
}

結論。 該方法實現較簡單, 當不願意使用功能較強大的第三方控制項陳列庫時可以採用這種方法,缺點是負責浮動的容器是一個視窗,不大美觀。 
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.