顯示具有 WindowForm 標籤的文章。 顯示所有文章
顯示具有 WindowForm 標籤的文章。 顯示所有文章

2018年4月3日 星期二

Windows Form 將 FormBorderStyle 設為 none 時,視窗的拖曳方式

因為專案畫面上的需求(Form 表頭的顏色與設計),
所以將 Windows Form 的 FormBorderStyle 設定 none 後,再自行加上 TableLayoutPanel (tableLayoutPanel1) 等控制項來偽裝

此時如果遇上使用者使用的電腦解析度,低於設計時,會造成畫面被切掉,此時因為 FormBorderStyle 設為 none,所以 Form 也拉不動,所以需要再對於拖曳功能加工(沒事找事做)
對於 Form 內的控制項可以單純的在 MouseDown(按下滑鼠)、DragEnter(拖曳開始)、DragDrop(拖曳結束) 事件中寫下相對應的語法,可參考 在 Windows Form 中執行拖放作業

但現在是在 Windows Form 外執行拖放作業,可以用win32 的角度來撰寫語法
// win32 的角度來撰寫語法
public const int WM_NCLBUTTONDOWN = 0xA1;
public const int HT_CAPTION = 0x2;

[System.Runtime.InteropServices.DllImportAttribute("user32.dll")]
public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
[System.Runtime.InteropServices.DllImportAttribute("user32.dll")]
public static extern bool ReleaseCapture();

// 再在 tableLayoutPanel1 的 MouseDown 事件寫下
private void tableLayoutPanel1_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{     
    if (e.Button == MouseButtons.Left)
    {
        ReleaseCapture();
        SendMessage(Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0);
    }
}
或是在 tableLayoutPanel1 的 MouseDown、MouseMove 事件撰寫語法
// 在 tableLayoutPanel1 的 MouseDown、MouseMove 事件撰寫語法
private Point startPoint;   // 紀錄目前視窗的位置
private void tableLayoutPanel1_MouseDown(object sender, MouseEventArgs e)
{
    //當滑鼠擊以左點擊控制項的範圍內時,透過計算紀錄目前視窗的位置
    if (e.Button == MouseButtons.Left)
    {
        startPoint = new Point(-e.X + SystemInformation.FrameBorderSize.Width, -e.Y - SystemInformation.FrameBorderSize.Height);
    }
}

private void tableLayoutPanel1_MouseMove(object sender, MouseEventArgs e)
{
    // 當滑鼠擊按著左鍵移動時,記錄下移動的位置
    if (e.Button == MouseButtons.Left)
    {
        // 滑鼠指標的位置
        Point mousePos = Control.MousePosition;
        // 新視窗的位置(等於滑鼠指標目前的位置與先前視窗位置的位移)
        mousePos.Offset(startPoint.X, startPoint.Y);
        // 改變視窗位置
        Location = mousePos;
    }
}

2018年1月17日 星期三

C# Window Form - 動態指定Form尺寸

如果想要動態控制 Form 的尺寸,做法會先指定以某個控制項(或原點)做為基準,指定控制項的位置後,確定最右下角的那個控制項之後,才能決定 Form 的尺寸。

比方右下角有一個 Button(button1),指定的 Form 的語法會是
this.Height = button1.Top + button1.Height;
this.Width = button1.Left + button1.Width;
但這樣加完的結果是看不到,因為 Form 的最上方有一條標題列,要再加上這標題列的高度才行,所以改成
this.Height = button1.Top + button1.Height + iControlSpacer + (this.Height-this.ClientSize.Height);
this.Width = button1.Left + button1.Width + iControlSpacer + (this.Width - this.ClientSize.Width);
其中 this.Height-this.ClientSize.Height 是標題列高度的計算方式,
iControlSpacer  是控制項之間的間隔

2016年7月21日 星期四

在 WinForm 下,ComboBox 下拉選單內容太長時,文字會被切掉

在 WinForm 下,ComboBox 下拉選單內容太長時,文字會被切掉










// 動態改變顯示的長度
private void Form1_Load(object sender, EventArgs e)
{
    DataTable dt = new DataTable();
    dt.Columns.Add("myID");
    dt.Columns.Add("myValue");
    dt.Rows.Add(new object[] { "1", "Bermuda 百慕達" });
    dt.Rows.Add(new object[] { "2", "Bosnia and Herzegovina 波希尼亞及赫塞哥維那" });
    cbxExamination.DataSource = dt;
    cbxExamination.DisplayMember = "myValue";
    cbxExamination.ValueMember = "myID";
    // 在資料繫結後加入以下語法
    SetDropDownWidth(comboCountry);
}
/// <summary>
/// 設定下拉選單下拉後的長度為最長內容的長度
/// </summary>
/// <param name="myCombo"></param>
/// <returns></returns>
private void SetDropDownWidth(ComboBox myCombo)
{
    int maxSize = 0;
    System.Drawing.Graphics g = CreateGraphics();
    for (int i = 0; i < myCombo.Items.Count; i++)
    {
        myCombo.SelectedIndex = i;
        SizeF size = g.MeasureString(myCombo.Text, myCombo.Font);
         if (maxSize < (int)size.Width)
         {
             maxSize = (int)size.Width;
          }
    }
    myCombo.DropDownWidth = myCombo.Width;
    if (myCombo.DropDownWidth < maxSize)
    {
        myCombo.DropDownWidth = maxSize;
    }
}
結果如下