2013-07-15 2 views
2

사용자가 그리드 행에 직접 입력하는 모눈 셀 값에서 Rectangle을 추가합니다. 특정 열의 값을 수정할 때 ThicknessHeight이라고 말하면 선택된 행 사각형의 수는 Height으로 증가하지만 선택된 행 사각형 뒤의 모든 사각형을 정확히 다시 정렬하지는 않습니다. xaml.cs wpf에서 사각형의 높이를 수정 한 후 캔버스에서 사각형을 다시 정렬하는 방법은 무엇입니까?

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; 
     } 

NEW EVENT 방법

에서

:

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 열의 값을 HeightRectangle으로 수정하면 캔바스에 반영되지만 아래의 다른 사각형은 현재 사각형의 변경된 높이 뒤에 나타나야합니다.

참고 : 내 응용 프로그램에는 WrapPanel을 사용할 수 없습니다. 캔버스를 사용하여 기존 코드를 수정하기 만하면됩니다.

도움말 감사드립니다!

는 CellChange 이벤트에서 루프를 들어 수정 : 당신이 정말이에 대한 ItemsControl 같은 것을 사용하는 것이 좋습니다 그러나 Canvas로도 수행 할 수 있습니다 무엇을 찾고 있는지

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를 사용하도록 강요

해결 방법 : 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); 
    } 
} 

지금이 함수를 호출하고 다시 위치 할 요소가 따라 맞게 새로운 차원. 귀하의 코드에서, 그것은 "편집"모드에서 새 높이를 설정 한 후 gridInner_CellValueChanged(...) 함수에서 호출됩니다. 당신이 시도해야합니까

:

을 당신이 필요 누구든지 설득하고 ItemsControl 같은 것을 사용하는 얻을 수 있도록 할 경우이 너무 간단합니다.

거친 예를 말 :

XAML이 될 수있다 : Items

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

코드에 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 라인의 작업과 같습니다.

ItemsControl을 코드 숨김으로 참조하는 것보다 기존 컨트롤을 조정해야하는 경우 Items 속성을 직접 사용할 수도 있습니다. Binding은 뷰에 대한 업데이트를 자동으로 처리해야합니다.

+0

안녕하세요 @Viv 답장을 보내 주셔서 감사합니다! 하지만이 코드는 기존 크기를 늘릴 때만 작동하지만 크기를 줄이면 다시 정렬하지 않습니다.! 어떤 생각? –

+0

@SHEKHARSHETE 예치 이전 항목이 확장되어 축소되지 않았는지 확인하는 것이 좋지 않은 Yeh입니다. 내 대답에 함수를 업데이트했습니다. 시도 해보면 좋을 것입니다. – Viv

+0

안녕하세요? 그것은 잘 작동 ..! 고마워요. ..! :) 정말 고마워! –

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; 



        } 

는 모든 지금 .. 감사 작품!

관련 문제