2013-07-15 29 views
2

我从正由用户直接在网格行输入格的单元格值添加Rectangle。当我修改特定的列值说ThicknessHeight然后再它增加了选择行矩形Height但选择行矩形后究竟它不重新安排它下面的所有矩形。如何在修改wpf中任何矩形的高度后在画布上重新排列矩形?

在xaml.cs

public class MyLayer : INotifyPropertyChanged 
{ 

    public string Thickness { get; set; } 
    public string OffsetRight { get; set; } 
    public string OffsetLeft { get; set; } 
    public string Material { get; set; } 
    public string MaterialPopup { get; set; } 
    public Rectangle rectangle { get; set; } 

    public GlassRectangle GlassRectangle { get; set; } 
    public MaterialLayer() 
    { 
     GlassRectangle = new GlassRectangle(); 

    } 
    event PropertyChangedEventHandler INotifyPropertyChanged.PropertyChanged 
    { 
     add { } 
     remove { } 
    } 
} 

public class GlassRectangle 
{ 

    public Rectangle Rectangle { get; set; } 
    public double Top = 0; 
    public GlassRectangle() 
    { 
     Rectangle = new Rectangle(); 

    } 
} 

private void gridInner_CellValueChanged(object sender, DevExpress.Xpf.Grid.CellValueChangedEventArgs e) 
     { 
      string cellValue = string.Empty; 
      MyLayer currentLayer = ((MyLayer)(e.Row)); 

      if (e.Column.HeaderCaption.ToString() == "Thickness") 
      { 

       cellValue =(e.Value.ToString()); 
       //there is alredy a rectangle - means this is edit mode 
       if (currentLayer.rectangle != null) 
       { 
        currentLayer.rectangle.Height = Convert.ToDouble(cellValue); 
        currentLayer.rectangle.Stroke = new SolidColorBrush(Color.FromRgb(0, 255, 0)); 

       } 
       //else this is insert mode 
       else 
       { 

        currentLayer.rectangle = CreateRectangle(cellValue); 
       } 

      } 

     } 

protected Rectangle CreateRectangle(string cellval) 
     { 
      Rectangle newrect = new Rectangle(); 
      newrect.Stroke = Brushes.Red; 
      newrect.StrokeThickness = 1; 
      if (cellval.ToString().Contains(".")) 
      { 
       newrect.Height = Convert.ToDouble(cellval) * 100; 
      } 
      else 
      { 
       newrect.Height = Convert.ToDouble(cellval); 
      } 
      newrect.Width = width; 
      Canvas.SetLeft(newrect, 100); 
      double canvasTop = 0.0; 
      if (canvasboard.Children.Count > 0) 
      { 
       var lastChildIndex = canvasboard.Children.Count - 1; 
       var lastChild = canvasboard.Children[lastChildIndex] as FrameworkElement; 
       if (lastChild != null) 
        //lastChild.Height-1: so that it come extactly on existing if set to +1 it comes below first rectangle 
        canvasTop = Canvas.GetTop(lastChild) + lastChild.Height - 1; 
      } 

      Canvas.SetTop(newrect, canvasTop); 
      val = val + 1; 
      newrect.Tag = val; 
      canvasboard.Children.Add(newrect); 
      //rectangle = rect; 

      foreach (UIElement ui in canvasboard.Children) 
      { 
       if (ui.GetType() == typeof(Rectangle)) 
       { 
        itemstoremove.Add(ui); 
       } 
      } 

      return newrect; 
     } 

新的事件方法:

private void gridMaterialInner_CellValueChanged(object sender, DevExpress.Xpf.Grid.CellValueChangedEventArgs e) 
     { 
      string cellValue = string.Empty; 
      string cellOldValue = string.Empty; 
      MyLayer currentLayer = ((MyLayer)(e.Row)); 
      if (e.Column.HeaderCaption.ToString() == "Thickness") 
      { 
       //current cell value 
       cellValue =(e.Value.ToString());// GetRowCellValue(e.RowHandle, gridMaterialInner.Columns["LastName"]).ToString(); 
       //there is alredy a rectangle - means this is edit mode 
       double currentheight = 0.0; 
       double oldht = 0.0; 
       // old cell value 
       if (e.OldValue != null) 
       { 
        cellOldValue = (e.OldValue.ToString()); 
       } 
       if (currentLayer.rectangle != null) 
       { 
        if (cellValue.ToString().Contains(".")) 
        { 
         currentheight = Convert.ToDouble(cellValue) * 100; 
        } 
        else 
        { 
         currentheight = Convert.ToDouble(cellValue) * 100; 
        } 
        if (cellOldValue.ToString().Contains(".")) 
        { 
         oldht = Convert.ToDouble(cellOldValue) * 100; 
        } 
        else if(cellOldValue!=string.Empty) 
        { 
         oldht = Convert.ToDouble(cellOldValue) * 100; 
        } 

        currentLayer.rectangle.Height = currentheight; 
        currentLayer.rectangle.Stroke = new SolidColorBrush(Color.FromRgb(0, 255, 0)); 

        //Refresh(); 
        //Get the index of selected row 
        int layerIndex = materialBindlist.IndexOf(currentLayer); 
        for(int i = layerIndex; i < materialBindlist.Count-1; i++) 
        { 
         //set the top position of all other rectangles that are below selected rectangle/row 
         //(Current-Old)+Top 
         Canvas.SetTop(materialBindlist[i + 1].rectangle, (currentheight - oldht) + materialBindlist[i + 1].GlassRectangle.Top); 
         //Canvas.SetTop(materialBindlist[i].rectangle, (currentheight - oldht) + materialBindlist[i + 1].GlassRectangle.Top); 

        } 
       } 
       //else this is insert mode 
       else 
       { 
        //MaterialLayer object 
        currentLayer.rectangle = CreateRectangle(cellValue); 
        //store Top & Rectangle object in GlassRectangle class which is referenced in MaterialLayer class 
        currentLayer.GlassRectangle.Rectangle = currentLayer.rectangle; 
        currentLayer.GlassRectangle.Top = canvasTop; 
       } 

      } 

     } 

这创建在画布上其他类似的堆叠的商品后矩形之一。但是,当我修改Thickness列这是RectangleHeight的价值反映在画布上,但其他矩形下方必须当前矩形的不同高度后出现。

注:我不能在我的应用程序中使用WrapPanel。只需使用Canvas修改现有代码即可。

帮助感激!

修改for循环CellChange事件:

int layerIndex = materialBindlist.IndexOf(currentLayer); 
        for(int i = layerIndex; i < materialBindlist.Count-1; i++) 
        { 
         //set the top position of all other rectangles that are below selected rectangle/row 
         //(Current-Old)+Top 
         double top=Convert.ToDouble((currentHeight - oldHeight) + materialBindlist[i + 1].GlassRectangle.Top); 
         Canvas.SetTop(materialBindlist[i + 1].rectangle,top); 

         materialBindlist[i + 1].GlassRectangle.Top = top; 



        } 
+1

转储画布并写入覆盖度量和排列的自定义面板。 –

回答

3

您要查找的内容可以用Canvas甚至做不过你真的应该考虑使用类似的ItemsControl这一点。

解决方案时,被迫使用Canvas

private void Refresh() { 
    for (int i = 1; i < canvasboard.Children.Count; ++i) { 
    var currentElement = canvasboard.Children[i] as FrameworkElement; 
    var previousElement = canvasboard.Children[i - 1] as FrameworkElement; 
    if (currentElement == null || previousElement == null) 
     return; 
    var requiredTop = Canvas.GetTop(previousElement) + previousElement.Height - 1; 
    if (Math.Abs(Canvas.GetTop(currentElement) - requiredTop) > 0.0) 
     Canvas.SetTop(currentElement, requiredTop); 
    } 
} 

现在调用这个函数“之后”更改现有元素的大小在Canvas,它会重新定位的元素据此,以适应新维度。在您的代码中,在“编辑”模式下设置新高度后,将从gridInner_CellValueChanged(...)函数中调用该函数。

你应该尽量做到:

如果你能说服你需要谁,并获得使用类似的ItemsControl,这将是这么简单得多。

说一个粗略的例子:

XAML可能是:

<ItemsControl ItemsSource="{Binding Items}"> 
    <ItemsControl.ItemsPanel> 
    <ItemsPanelTemplate> 
     <VirtualizingStackPanel Orientation="Vertical" /> 
    </ItemsPanelTemplate> 
    </ItemsControl.ItemsPanel> 
</ItemsControl> 

Items宣布为代码public ObservableCollection<Rectangle> Items { get; set; }

现在你Add()功能可能只是:

private void Add() { 
    var rect = new Rectangle { 
    Stroke = Brushes.Red, 
    StrokeThickness = 1, 
    Height = Convert.ToDouble(txtheight.Text), 
    Width = 100 
    }; 
    Items.Add(rect); 
} 

和更新,当你编辑现有的控制的,这将是在这种情况下自动的。由于Layout容器为您处理所有这些混乱,因此没有硬编码的定位。

您可以将Items集合类型切换为您自己的自定义控件类型MyLayer,并且在实施INPC时,更改仍然会自动进行。您现在必须定义DataTemplate才能让您的物品呈现,但这就像xaml中的3行工作。

您还可以在需要调整现有控件时直接使用Items属性,而不必在代码隐藏中引用ItemsControl。绑定应该自动处理视图的更新。

+0

嗨@Viv感谢您的回复!但这个代码只有当我增加现有的大小,但是当我再次减小大小时,它不会重新安排..!任何想法? –

+0

@SHEKHARSHETE Yeh那是我的错,我只是在检查之前的项目扩展和不缩小。我已经更新了我的答案中的功能。试试看,应该没问题。 – Viv

+0

嘿@Viv你摇滚!它工作正常..!非常感谢..! :)我真的很感谢你的工作! –

1

修改为可循环在小区改变事件:

int layerIndex = materialBindlist.IndexOf(currentLayer); 
        for(int i = layerIndex; i < materialBindlist.Count-1; i++) 
        { 
         //set the top position of all other rectangles that are below selected rectangle/row 
         //(Current-Old)+Top 
         double top=Convert.ToDouble((currentHeight - oldHeight) + materialBindlist[i + 1].GlassRectangle.Top); 
         Canvas.SetTop(materialBindlist[i + 1].rectangle,top); 

         materialBindlist[i + 1].GlassRectangle.Top = top; 



        } 

现在的工作..感谢所有!