线角点上的拇指不会重新定位点

时间:2012-11-07 18:37:54

标签: c# wpf

我正在开发一个绘图应用程序,其中可以绘制各种类型的线条。在线角点我使用itemsControl放置了一个拇指。当用户用鼠标点击它并拖动鼠标时,拇指应移动该角点。现在发生的事情是,当我这样做时,点和拇指会移动一点点,但是它会立即失去鼠标捕捉并且不再移动。当我调试正确触发的第一个dragdelta事件时,从发送拇指到itemscontrol以及更远的地方跟踪了一个完整的可视树,但有时当它下次触发时,拇指的位置尚未更新,并且包含的​​内容呈现者在可视化树中具有null父项。

这是与行拇指点相关的xaml部分:

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

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是线类。 undo绑定的作用是使toolLine将Canvas.Left和Canvas.Top设置为0,但缩放点以使它们仍位于同一点 - 即添加旧的Canvas.Left和Canvas。工具线的最高值到线中的每个点。

重新生成边界项的代码如下:

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

PointRelocateThumb的模板是一个宽度和高度为7的椭圆 - 这解释了为什么我必须将所有拇指位置偏移3.5。

1 个答案:

答案 0 :(得分:0)

问题出在regenerateObserableCollection

我不得不修改和销毁所有LineCornerObjects,而是修改了observable集合中包含的LineCornerPoints。