2013-07-11 52 views
1

我是WPF的新手。我在按鈕單擊上在Canvas上添加矩形。當我從TextBox設置特定矩形的高度。它與子矩形重疊。例如:如何使用C#在WPF中調整大小的父矩形旁邊的矩形?

例如:當有3個矩形Height=100,Width=200 &當我設置高度Second Rectangle to 150。那麼子Rectangle必須在第二個矩形&不得在第三個矩形上重疊後出現。可能嗎?

static int val=0; 
List<UIElement> itemstoremove = new List<UIElement>(); 
private void BtnAdd_Click(object sender, RoutedEventArgs e) 
     { 

      int heigt = 0; 
      int wegt = 0; 
      if (!string.IsNullOrEmpty(txtHeight.Text) && !string.IsNullOrEmpty(txtWidth.Text)) 
      { 
       heigt = int.Parse(txtHeight.Text); 
       wegt = int.Parse(txtWidth.Text); 
      } 
      rect = new Rectangle(); 
      rect.Stroke = Brushes.Red; 
      rect.StrokeThickness = 2; 
      rect.Height = heigt; 
      rect.Width = wegt; 
      Canvas.SetLeft(rect, 10); 
      Canvas.SetTop(rect, (rect.Height) * val); 
      rect.Tag = val; 
      canvasboard.Children.Add(rect); 
      val = val + 1; 
      //canvasboard is Canvas object 
      foreach (UIElement ui in canvasboard.Children) 
      { 
       if (ui.GetType() == typeof(Rectangle)) 
       { 
        itemstoremove.Add(ui); 
       } 
      } 
     } 

修改高度&寬度:

private void BtnModify_Click(object sender, RoutedEventArgs e) 
     { 
      int heigt = 0; 
      int wegt = 0; 
      if (!string.IsNullOrEmpty(txtHeight.Text) && !string.IsNullOrEmpty(txtWidth.Text)) 
      { 
       heigt = int.Parse(txtHeight.Text); 
       wegt = int.Parse(txtWidth.Text); 
      } 
      Rectangle rectToRemove; 

      foreach (UIElement ui in itemstoremove) 
      { 
       if (ui.GetType() == typeof(Rectangle) && ((Rectangle)ui).Tag.ToString() == txtModifyRect.Text) 
       { 
        rectToRemove = ui as Rectangle; 
        //itemstoremove.Remove(rectToRemove); 
        rectToRemove.Height = heigt; 
        rectToRemove.Width = wegt; 
        //canvasboard.Children.Remove(rectToRemove); 
        break; 
       } 
      } 
     } 

這工作得很好。 只是我想防止彼此重疊Rectangle,並且必須使用自動調整一個接一個出現。

幫助讚賞!

回答

0

聽起來像你想爲你的矩形StackPanel。您可以將StackPanel嵌套在網格中。

1

爲了得到您想要的效果,您必須將畫布更改爲WrapPanel。 通過這種方式,當您將孩子添加到畫布上時,您不會添加位置,它會自行排列對象。 基本上你想要這個

 <ScrollViewer VerticalScrollBarVisibility="Auto" > 
     <WrapPanel Name="objList" > </WrapPanel> 
     </ScrollViewer> 

的ScrollViewer中會讓你滾動,如果你有比窗口可以包含多個對象。

+0

你的意思是我必須添加矩形到WrapPanel?我是新來的,所以..! –

+0

這是一個非常好的建議,但作者希望將它們放在另一個之下,至少我認爲他在看到'Canvas.SetLeft(rect,10)後需要它。 Canvas.SetTop(rect,(rect.Height)* val);'.. – quetzalcoatl

+0

@SHEKHARSHETE:是的,他的確是這個意思。 WrapPanel將成爲矩形的容器,然後矩形會像HTML頁面上的文本一樣進行佈局:只要還有剩餘空間,然後換行到「新行」。 – quetzalcoatl

1

是否需要特別指定Canvas ..?即使在純WPF /桌面中,也有一些佈局組件可以完全自動地爲您完成此操作。

的行爲「堆疊」的組件陸續正是StackPanel類/組件/控制的作用:

<StackPanel x:Name="stacker" Orientation="Vertical"> 
    <Rectangle Width="30" Height="100" Background="Green" /> 
    <Rectangle Width="10" Height="50" Background="Blue" /> 
    <Rectangle Width="20" Height="80" Background="Red" Margin="5,10" /> 
</StackPanel> 

注意如何矩形根據其不同的定位Heights下一個彼此。請注意,我不必指定Orientation=Vertical,因爲StackPanel的默認行爲就是像這樣定位它們。如果你喜歡,你可以將它切換到水平,然後根據它們的Widths堆疊它們。您也可以微調並添加一些額外的間距,例如Margin,就像在第三個矩形中一樣。

如果您需要通過代碼完成此操作,那麼名爲的stacker就非常適合它:您可以動態添加新元素,並且會添加新元素,就像XAML中定義的子元素一樣:在另一個下。

隨着StackPanel,你會得到更多! StackPanel觀察它的孩子。如果在放置孩子後的某段時間改變了孩子的身高/體寬,那麼StackPanel會立即調整位置,這樣他們都不會重疊(如果你讓孩子變小,它會擠壓孩子,如果你讓孩子變大 - 將擴大等)。

如果你真的,真的想用Canvas,然後在加入-一個新項目的時候,你將不得不遍歷存儲在畫布上現有的所有項,總結自己的高度,和將新項目的Y位置設置爲,恰恰相當於。這樣,它將在最後一個元素下正好顯示爲。這是最明顯的做法。但是,它不會考慮可能發生在Canvas上的邊距,間距和其他一些細節。

一個更好但不太明顯的方法是不要一次又一次地總結高度,而是根據最下面的現有項目定位新項目。畢竟,所有舊物品的位置都正確,對嗎?但是,bottommost是什麼意思?有時候,位於頂部附近的高個子物品可能會比坐在中間的不那麼高的物品更向下。因此,bottommost並不意味着the item with maximum Y position,而是指具有最遠Bottom的項目,所以maximum Y+Height。所以:

  • 循環通過現有項目
  • 查找其Size.Height+Position.Bottom是最大的
  • 設置新項目的Position.Y該值

現在一個項目,你會得到大致與StackPanel一樣 - 但它只會是一次性效果。 (*)

編輯: (*)我不記得確切的,但如果X/Y/Bottom屬性是DependencyProperty,那麼你甚至可以嘗試使用Bindings自動控制位置。 Tha在Canvas上可能很有趣。試着將後一個元素的Y綁定到前者的Bottom,它應該全部神奇地佈置它們自己,甚至在移動/調整大小時自動更新。不過,請先嚐試StackPanel!

+0

FYI:文章:[MSDN - 佈局容器比較](http://msdn.microsoft.com/en-us/圖書館/ bb514628(v = vs.90).aspx) – quetzalcoatl

+0

甚至更​​好,圖片顯示每個容器工作的鋤頭:[面板和容器](http://www.dotnetfunda.com/articles/article900-wpf-tutorial-佈局面板的容器佈局改造,2.aspx) – quetzalcoatl

0

這裏是我的解決方案:

<ScrollViewer VerticalScrollBarVisibility="Auto" Width="250" Height="500"> 
       <WrapPanel Name="wrapboard" Orientation="Vertical" ></WrapPanel> 
    </ScrollViewer> 

private void BtnAdd_Click(object sender, RoutedEventArgs e) 
     { 

      int heigt = 0; 
      int wegt = 0; 
      if (!string.IsNullOrEmpty(txtHeight.Text) && !string.IsNullOrEmpty(txtWidth.Text)) 
      { 
       heigt = int.Parse(txtHeight.Text); 
       wegt = int.Parse(txtWidth.Text); 
      } 
      rect = new Rectangle(); 
      rect.Stroke = Brushes.Red; 
      rect.StrokeThickness = 2; 
      rect.Height = heigt; 
      rect.Width = wegt; 
      rect.Tag = val; 
      wrapboard.Children.Add(rect); 
      val = val + 1; 
      //wrapboard is WrapPanel object 
      foreach (UIElement ui in wrapboard.Children) 
      { 
       if (ui.GetType() == typeof(Rectangle)) 
       { 
        itemstoremove.Add(ui); 
       } 
      } 
     } 
相關問題