0
WPFキャンバスの子要素にマウスの位置を正しく配置するのが難しい
以下のコードでは、子画像付きのキャンバスがあります。子画像はドラッグアンドドロップで追加され、キャンバス自体は外側のグリッド内に含まれます。子画像上にルーペを使用する場合、拡大される領域のソースはルーペよりも高くなります。 (ソースコード:A Magnifier)
これはどのように修正されましたか?
結果の画像。拡大鏡の中心は「S」の上にあり、右下にはありません。
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);
}
サンプルはsliderTargetSize、BoolToVis aとbが欠落しています。ImageCanvasBehavior –
@WaltRitscher簡潔にするために省略します。いずれにしても、これらのどれもマウスに対してルーペを配置しません。 ImageCanvasBehaviorを使用すると、キャンバス上に画像をドラッグ&ドロップできます。 (それ以外は何もしない)。 BoolToVisは可視性に対する標準のtrue/falseであり、SliderTargetSizeはValueChangedイベントに置き換えられました。 –