2017-04-23 10 views
0

WPFキャンバスの子要素にマウスの位置を正しく配置するのが難しい

以下のコードでは、子画像付きのキャンバスがあります。子画像はドラッグアンドドロップで追加され、キャンバス自体は外側のグリッド内に含まれます。子画像上にルーペを使用する場合、拡大される領域のソースはルーペよりも高くなります。 (ソースコード:A Magnifier

これはどのように修正されましたか?

結果の画像。拡大鏡の中心は「S」の上にあり、右下にはありません。

Mouse Position is wrong

XAML: 
<ScrollViewer Name="TheScrollViewer" Grid.Row ="2" Grid.RowSpan="2" Grid.Column="1" Grid.ColumnSpan="2" VerticalScrollBarVisibility="Auto" > 

      <Grid ShowGridLines="True" > 
       <Grid.ColumnDefinitions> 
        <ColumnDefinition Width="60"/> 
        <ColumnDefinition Width="*"/> 
       </Grid.ColumnDefinitions> 
       <Grid.RowDefinitions> 
        <RowDefinition/> 
        <RowDefinition/> 
       </Grid.RowDefinitions> 

     <Canvas Grid.Column="1" Grid.Row="1" Background="Blue" Name="mainUI" PreviewMouseMove="OnMoveOverMainUI" 
         Panel.ZIndex="{Binding ImageLayer.ZIndex}" Visibility="{Binding ImageLayer.Visibility}" > 
        <i:Interaction.Behaviors> 
         <b:ImageCanvasBehavior Source ="{Binding ImageLayer.Source}" /> 
        </i:Interaction.Behaviors> 
       </Canvas> 
<Canvas HorizontalAlignment="Left" VerticalAlignment="Top" Grid.Column="1" Grid.Row="1" Panel.ZIndex="1000" > 
        <Canvas Name="magnifierCanvas" IsHitTestVisible="False" 
           Visibility="{Binding ElementName=checkEnableMagnifier,Path=IsChecked, Converter={StaticResource BoolToVis}}"> 
         <Line StrokeThickness="30" X1="200" Y1="200" X2="300" Y2="300"> 
          <Line.Stroke> 
           <LinearGradientBrush StartPoint="0.78786,1" EndPoint="1,0.78786"> 
            <GradientStop Offset="0" Color="DarkGreen" /> 
            <GradientStop Offset="0.9" Color="LightGreen" /> 
            <GradientStop Offset="1" Color="Green" /> 
           </LinearGradientBrush> 
          </Line.Stroke> 
         </Line> 
         <Ellipse Width="250" Height="250" Fill="White" /> 
         <Ellipse Width="250" Height="250" Name="magnifierEllipse" StrokeThickness="3"> 
          <Ellipse.Fill> 
           <VisualBrush ViewboxUnits="Absolute" Viewbox="0,0,50,50" 
         ViewportUnits="RelativeToBoundingBox" Viewport="0,0,1,1"/> 
          </Ellipse.Fill> 
          <Ellipse.Stroke> 
           <LinearGradientBrush StartPoint="0,0" EndPoint="0,1"> 
            <GradientStop Offset="0" Color="#AAA" /> 
            <GradientStop Offset="1" Color="#111" /> 
           </LinearGradientBrush> 
          </Ellipse.Stroke> 
         </Ellipse> 
         <Ellipse Canvas.Left="2" Canvas.Top="2" StrokeThickness="4" Width="246" Height="246"> 
          <Ellipse.Stroke> 
           <LinearGradientBrush StartPoint="0,0" EndPoint="0,1"> 
            <GradientStop Offset="0" Color="#555" /> 
            <GradientStop Offset="1" Color="#EEE" /> 
           </LinearGradientBrush> 
          </Ellipse.Stroke> 

         </Ellipse> 
        </Canvas> 
       </Canvas> 
      </Grid> 
     </ScrollViewer> 

Code-Behind: 
    private void ZoomChanged(object sender, EventArgs e) 
     { 
      if (magnifierEllipse != null) 
      { 
       VisualBrush b = (VisualBrush)magnifierEllipse.Fill; 
       Rect viewBox = b.Viewbox; 
       double val = sliderTargetSize.Value; 
       viewBox.Width = val; 
       viewBox.Height = val; 
       b.Viewbox = viewBox; 
      } 
     } 

     private void OnMoveOverMainUI(object sender, MouseEventArgs e) 
     { 
      VisualBrush b = (VisualBrush)magnifierEllipse.Fill; 
      Point pos = e.MouseDevice.GetPosition(mainUI); 
      Rect viewBox = b.Viewbox; 
      double xoffset = viewBox.Width/2.0; 
      double yoffset = viewBox.Height/2.0; 
      viewBox.X = pos.X - xoffset; 
      viewBox.Y = pos.Y - yoffset; 
      b.Viewbox = viewBox; 
      Canvas.SetLeft(magnifierCanvas, pos.X - magnifierEllipse.Width/2); 
      Canvas.SetTop(magnifierCanvas, pos.Y - magnifierEllipse.Height/2); 
     } 
+0

サンプルはsliderTargetSize、BoolToVis aとbが欠落しています。ImageCanvasBehavior –

+0

@WaltRitscher簡潔にするために省略します。いずれにしても、これらのどれもマウスに対してルーペを配置しません。 ImageCanvasBehaviorを使用すると、キャンバス上に画像をドラッグ&ドロップできます。 (それ以外は何もしない)。 BoolToVisは可視性に対する標準のtrue/falseであり、SliderTargetSizeはValueChangedイベントに置き換えられました。 –

答えて

0

は、問題を修正しました。この手順は、独自のウィンドウではうまくいきます。グリッド内のユーザーコントロールではそうではありません。

private void OnMoveOverMainUI(object sender, MouseEventArgs e) 
     { 
      VisualBrush b = (VisualBrush)magnifierEllipse.Fill; 
      Point pos = e.MouseDevice.GetPosition(mainUI); 
      Rect viewBox = b.Viewbox; 
      double xoffset = viewBox.Width/2.0; 
      double yoffset = viewBox.Height/2.0; 
      viewBox.X = pos.X - xoffset; 
      viewBox.Y = pos.Y - yoffset; 
      b.Viewbox = viewBox; 
      Canvas.SetLeft(magnifierCanvas, pos.X - magnifierEllipse.Width/2); 
      Canvas.SetTop(magnifierCanvas, pos.Y - magnifierEllipse.Height/2); 
     } 

私は必要な修正版は次のとおりです。

private void OnMoveOverMainUI(object sender, MouseEventArgs e) 
       { 
        // Get position of the mainUI to its ancestor the MainGrid 
        Point relativePoint = mainUI.TransformToAncestor(MainGrid) 
            .Transform(new Point(0, 0)); 

        // Get position of the Mouse relative to the mainUI 
        Point pp = e.MouseDevice.GetPosition(mainUI); 

        // Get position of the mouse relative to the MainGrid. 
        Point pos = new Point(pp.X + relativePoint.X, pp.Y + relativePoint.Y); 

        VisualBrush b = (VisualBrush)magnifierEllipse.Fill; 

        Rect viewBox = b.Viewbox; 
        double xoffset = viewBox.Width/2.0; 
        double yoffset = viewBox.Height/2.0; 
        viewBox.X = pos.X - xoffset; 
        viewBox.Y = pos.Y - yoffset; 
        b.Viewbox = viewBox; 
        Canvas.SetLeft(magnifierCanvas, pos.X - magnifierEllipse.Width/2 - relativePoint.X); 
        Canvas.SetTop(magnifierCanvas, pos.Y - magnifierEllipse.Height/2 - relativePoint.Y); 
} 
関連する問題