WPF
在下面的代码中,我有一个带有子图像的Canvas。通过拖放添加子图像,并且Canvas本身包含在外部Grid中。当在儿童图像上使用放大镜时,被放大的区域的源更高并且放大器的左侧。 (源代码改编自: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);
}
答案 0 :(得分: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);
}