2012-11-07 8 views
5

Opracowuję aplikację do rysowania, w której można rysować różne typy linii. W punktach narożnych linii umieściłem kciuk za pomocą elementu Sterowanie. Kciuki powinny przesuwać ten punkt narożny, gdy użytkownik kliknie lewym przyciskiem myszy i przeciągnie myszą. To, co się teraz dzieje, polega na tym, że kiedy to robię, punkt i kciuk poruszają się trochę, ale potem od razu tracą zdolność przechwytywania myszy i nie poruszają się już. Podczas debugowania pierwsze zdarzenie dragdelta, które zostanie poprawnie uruchomione, ma pełne wizualne drzewo odczytywane z kciuka wysyłającego do kontroli przedmiotów i poza nią, ale czasami, gdy strzela następnym razem, lokalizacja kciuka nie została zaktualizowana, a osoba wyświetlająca zawartość zawierała ma null rodziców w drzewie wizualnym.Kciuki na punktach narożnych linii nie przenoszą punktów

to część xaml związanych w punktach linii zasada:

<ItemsControl x:Name="PART_LineRelocate" ItemsSource="{Binding pointsObservableCollection}" Visibility="Collapsed" > 
    <ItemsControl.ItemTemplate> 
     <DataTemplate DataType="{x:Type s:LineCornerPoint}" > 
      <Grid> 
       <c:PointRelocateThumb VerticalAlignment="Center" HorizontalAlignment="Center" Focusable="True" x:Name="PART_PointRelocateThumb" Cursor="Hand"/> 
      </Grid> 
     </DataTemplate> 
    </ItemsControl.ItemTemplate> 
    <ItemsControl.ItemsPanel> 
     <ItemsPanelTemplate> 
      <Canvas IsItemsHost="True" /> 
     </ItemsPanelTemplate> 
    </ItemsControl.ItemsPanel> 
    <ItemsControl.ItemContainerStyle > 
     <Style > 
      <Style.Triggers> 
        <DataTrigger Value="BrokenLinkLine" Binding="{Binding RelativeSource={RelativeSource AncestorType={x:Type s:ToolLine}}, Path=indicator}" > 
         <Setter Property="Canvas.Left" Value="{Binding Corner.X}" /> 
         <Setter Property="Canvas.Top" Value="{Binding Corner.Y}" /> 
        </DataTrigger> 

        ....More of these datatriggers for the different types of lines 
       </Style.Triggers> 
     </Style> 
    </ItemsControl.ItemContainerStyle> 

kod dla PointRelocateThumb:

public PointRelocateThumb() 
    { 

     base.DragDelta += new DragDeltaEventHandler(this.PointRelocateThumb_DragDelta); 

    } 
    void PointRelocateThumb_DragDelta(object sender, System.Windows.Controls.Primitives.DragDeltaEventArgs e) 
    { 
     PointRelocateThumb prt = (PointRelocateThumb)sender; 
     LineCornerPoint lcp = (LineCornerPoint)prt.DataContext; 
     Point thumbPoint = new Point(Canvas.GetLeft((ContentPresenter)prt.TemplatedParent), Canvas.GetTop((ContentPresenter)prt.TemplatedParent)); 
     ToolLine toolLine = null; 
     DrawingCanvas designer = null; 
     ItemsControl itemsControl = ItemsControl.ItemsControlFromItemContainer(prt.TemplatedParent); 
     if (itemsControl != null) 
      toolLine = itemsControl.DataContext as ToolLine; 
     if (toolLine != null) 
      designer = VisualTreeHelper.GetParent(toolLine) as DrawingCanvas; 
     if (toolLine != null && designer != null && toolLine.IsSelected) 
     { 
      thumbPoint = new Point(thumbPoint.X + Canvas.GetLeft(toolLine) + 3.5, thumbPoint.Y + Canvas.GetTop(toolLine) + 3.5); 

      toolLine.undoBounding(); 
      if (System.String.Compare(toolLine.indicator, "BrokenLinkLine") == 0 
       || System.String.Compare(toolLine.indicator, "LinkLine") == 0 
       || System.String.Compare(toolLine.indicator, "OrthogonalLinkLine") == 0 
       || System.String.Compare(toolLine.indicator, "BrokenLine") == 0 
       || System.String.Compare(toolLine.indicator, "Line") == 0 
       || System.String.Compare(toolLine.indicator, "Polygon") == 0) 
      { 
       if (toolLine.pathFigure.StartPoint.Equals(thumbPoint)) 
       { 
        toolLine.pathFigure.StartPoint = new Point(modifyingToolLine.pathFigure.StartPoint.X + e.HorizontalChange, modifyingToolLine.pathFigure.StartPoint.Y + e.VerticalChange);     } 
       else 
       { 
        foreach (LineSegment ls in toolLine.pathSegmentCollection) 

        { 
         if (ls.Point.Equals(thumbPoint)) 
         { 
          ls.Point = new Point(ls.Point.X + e.HorizontalChange, ls.Point.Y + e.VerticalChange); 
          break; 
         } 

        } 
       } 
      } 
      toolLine.regenerateBoundingItem(); 
     } 
     e.Handled = true; 
    } 
} 

}

Tooline jest linia klasa. To, co się cofa, polega na tym, że sprawia, że ​​toolLine ma Canvas.Left i Canvas.Top jest ustawiona na 0, ale skaluje punkty tak, że wciąż znajdują się w tym samym punkcie - np. Dodając stary Canvas.Left i Canvas. Najwyższe wartości wiersza narzędzia do każdego punktu w linii.

Kod dla regeneratu ograniczającego elementu jest poniżej:

public void regenerateBoundingItem() 
{ 
    //Following line of code just regenerates the underlying path for the toolLine from the 
    //new pathsegmentCollection and pathFigure start point. 
    regenerateThisLine(); 
    double leftMostPoint = double.MaxValue, topMostPoint = double.MaxValue, bottomMostPoint = double.MinValue, rightMostPoint = double.MinValue; 
    getBoundingPoints(ref leftMostPoint, ref topMostPoint, ref bottomMostPoint, ref rightMostPoint); 

    //subtracts leftMost point and topMostPoint from each point in the line 
    scaleLinePoints(leftMostPoint, topMostPoint); 
    Canvas.SetLeft(this, leftMostPoint); 
    Canvas.SetTop(this, topMostPoint); 
    this.Width = rightMostPoint - leftMostPoint; 
    this.Height = bottomMostPoint-topMostPoint; 
     regenerateObservableCollection(); 
     regenerateThisLine(); 
} 
private void regenerateObservableCollection() 
{ 
    if (this.pointsObservableCollection == null) 
     this.pointsObservableCollection = new ObservableCollection<LineCornerPoint>(); 
    this.pointsObservableCollection.Clear(); 
    LineCornerPoint startPt = new LineCornerPoint(new Point(this.pathFigure.StartPoint.X - 3.5, this.pathFigure.StartPoint.Y - 3.5)); 
    this.pointsObservableCollection.Add(startPt); 
    if (System.String.Compare(indicator, "BrokenLine") == 0 
     || System.String.Compare(indicator, "BrokenLinkLine") == 0 
     || System.String.Compare(indicator, "LinkLine") == 0 
     || System.String.Compare(indicator, "Polygon") == 0 
     || System.String.Compare(indicator, "Line") == 0) 
    { 
     foreach (LineSegment ls in pathSegmentCollection) 
     { 
      LineCornerPoint pt = new LineCornerPoint(new Point(ls.Point.X - 3.5, ls.Point.Y - 3.5)); 
      this.pointsObservableCollection.Add(pt); 
     } 
    } 
} 

Szablon PointRelocateThumb jest elipsą o szerokości i wysokości 7 - co wyjaśnia, dlaczego muszę zrównoważyć wszystkie lokalizacje kciuk przez 3,5.

Odpowiedz

0

Problem był z regenerateObserableCollection

Zamiast polanie i niszcząc wszystkie LineCornerObjects, musiałem zmodyfikować LineCornerPoints zawartych w zbiorach zaobserwowania.

Powiązane problemy