5

我正在开发一个绘图应用程序,可以在其中绘制各种类型的线条。在线角点上,我使用 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 是线类。撤消绑定的作用是它使 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。

4

1 回答 1

0

问题在于 regenerateObserableCollection

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

于 2012-11-08T17:25:49.360 回答