2011-04-09 12 views
1

我花了整整一天的時間試圖解決這個問題,但沒有取得令人滿意的結果。如何在給定的容器內水平居中多個對象?

我必須在它們的容器(面板)中放置一些標籤。如果只是一個標籤,那將是一件輕而易舉的事,但生活是不容易的,我必須寫居中多個對象和克服兩個問題的方法:

  1. 這可能是1之間的任何數量的標籤8,在設計時我不知道有多少。
  2. 我必須能夠指定標籤之間的確切間距。

如果不是因爲,這不會是這麼辛苦,經過一番思考,我想出了這一點:

private void panel1_Resize(object sender, EventArgs e) 
{ 
    int position = 1; 
    foreach (Label l in panel1.Controls) 
    { 
     CenterToParent(l, panel1.Controls.Count, position); 
     position++; 
    } 
} 

private static void CenterToParent(Label lbl, int qty, int pos) 
{ 
    lbl.SetBounds((lbl.Parent.Bounds.Width - lbl.Width) * pos/(qty + 1), 
        lbl.Location.Y, lbl.Width, lbl.Height); 
} 

但是這樣的標籤之間的空間將改變面板的寬度發生變化,這個間隙必須是固定的大小。這也是爲什麼我不能簡單地使用TableLayoutPanel。 PS:如果你會這麼友好,如果你不知道對象類型(只是它具有相同的屬性)而使CenterToParent方法有效,那將是非常有啓發性的。我有一種感覺,我將在不久的將來需要這個,我不知道如何去做。

回答

1

至少對於第二個問題,只需將Label lbl更改爲Control ctrl即可。這可以採取任意控制,並將其置於其父母身上,假設它是一個。你可能希望檢查這種情況。

更新:

我想過你的問題多一點。首先,如果您的面板上有任何非Label控件,則您的應用程序將在您的foreach循環期間崩潰。將其更改爲foreach (Control ctrl in panel1.Controls)。這也使用我對你的第二個問題的原始答案。

你的基本問題是,給定一些控件,它們必須水平居中在它們的父母上並且均勻分開。總寬度爲:(control1.Width + offset) + (control2.Width + offset) ... (controlN.Width + offset) - offset。這個的x座標(startX)如果(Parent.Width/2) - (TotalWidth/2)。現在,你知道的x座標,你就可以開始佈局,像這樣的控件:

control1.Left = startX; 
control2.Left = control1.Right + offset 
controlN.Left = control(N-1).Right + offset 

由於真正的代碼可能是這樣的:

const int Offset = 8; // for example 
int totalWidth = panel1.Controls.Cast<Control>().Aggregate(0, (value, ctrl) => value + ctrl.Width + Offset); 

for (int index = 0; index < panel1.Controls.Count; index++) 
{ 
    Control current = panel1.Controls[index]; 

    if (index == 0) 
    { 
     current.Left = startX; 
    } 

    else 
    { 
     current.Left = panel1.Controls[index-1].Right + Offset; 
    } 
} 

我承認沒有測試了這一點,但也許你會從這裏開始工作。祝你好運。

+0

這樣做,非常感謝!這些對象有點偏離中心,但僅僅因爲最後一個對象不需要偏移量,我已經爲_totalWidth_添加了一個' - Offset',現在它已經很完美了。我意識到可能會發生崩潰,但我知道該面板中只有標籤。對於最後的請求,我嘗試使用'Object',但從未想過使用'Control'。非常明顯。 :) – 2011-04-09 03:37:06