WPF滚动查看器未根据内容进行调整



我需要在我的WPF应用程序中显示一个图像,用透明画布覆盖它,并允许用户在上面画画。用户必须能够放大图像(放大和缩小(和"导航"图像,同时使用停靠在窗口底部和右侧的某种滚动条进行放大。为了启用图像缩放,我使用了ZoomBorder控件,如第二个答案所述。这是我的XAML代码:

<ScrollViewer x:Name="imageScroll" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto"  >
<local:ZoomBorder x:Name="backgroundZoomBorder" ClipToBounds="True" HorizontalAlignment="Center" VerticalAlignment="Center"  Width="{Binding CurrentImageWidth}" Height="{Binding CurrentImageHeight}"  >
<Grid x:Name="gridDrawing" MouseLeftButtonDown="background_MouseLeftButtonDown" MouseMove="background_MouseMove" MouseLeftButtonUp="background_MouseLeftButtonUp">                           
<Image  x:Name="mainImage"  Source="{Binding Path=WriteableBmp}" />
<Canvas x:Name="canvasDrawing"  Background="Transparent" />
</Grid>
</local:ZoomBorder>
</ScrollViewer>

然而,这是有效的,scollviewer不会根据内容的大小进行调整,如果图像被放大到最大值或缩小到最小值,它仍然是一样的。如果图像小于窗口区域,它应该消失,或者当图像缩放时有更大的范围。我可以将ScrollViever绑定到Image的转换大小或其他什么吗?或者有什么比ScrollViewer更好的控制方法吗?谢谢

ScrollViewer永远不会与ZoomBorder控件一起工作,因为它使用的是RenderTransformRenderTransform在通过布局系统后操纵您所看到的。因此,其大小永远不会改变,因此ScrollViewer永远不会激活。

通过将ZoomBorder修改为使用LayoutTransform,您可以使缩放(滚轮(功能工作,并且ScrollViewer将激活。但是,要使用鼠标进行平移操作,需要进行更大的修改。

以下是一些有效的示例代码:

使用LayoutTransform 的ZoomBorder

using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
namespace SO
{
public class ZoomBorder : Border
{
private FrameworkElement child;
private ScaleTransform GetScaleTransform(FrameworkElement element)
{
return (ScaleTransform)((TransformGroup)element.LayoutTransform)
.Children.First(tr => tr is ScaleTransform);
}
public override UIElement Child
{
get => base.Child;
set
{
if (value != null && value != Child)
Initialize(value);
base.Child = value;
}
}
public void Initialize(UIElement element)
{
child = (FrameworkElement)element;
if (child == null) return;
var group = new TransformGroup();
var st = new ScaleTransform();
@group.Children.Add(st);
child.LayoutTransform = @group;
child.RenderTransformOrigin = new Point(0.0, 0.0);
MouseWheel += child_MouseWheel;
PreviewMouseRightButtonDown += child_PreviewMouseRightButtonDown;
}
public void Reset()
{
if (child == null) return;
// reset zoom
var st = GetScaleTransform(child);
st.ScaleX = 1.0;
st.ScaleY = 1.0;
}
#region Child Events
private void child_MouseWheel(object sender, MouseWheelEventArgs e)
{
if (child != null)
{
var st = GetScaleTransform(child);
var zoom = e.Delta > 0 ? .2 : -.2;
if (!(e.Delta > 0) && (st.ScaleX < .4 || st.ScaleY < .4)) return;
st.ScaleX += zoom;
st.ScaleY += zoom;
}
}
void child_PreviewMouseRightButtonDown(object sender, MouseButtonEventArgs e)
{
Reset();
}
#endregion
}
}

滚动查看器平移行为通过鼠标拖动来处理平移的行为。

using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Interactivity;
namespace SO
{
public class ScrollViewerPanBehavior : Behavior<ScrollViewer>
{
private UIElement content;
private Point scrollMousePoint;
private double scrollHorizontalOffset;
private double scrollVerticalOffset;
public ScrollViewerPanBehavior()
{
}
protected override void OnAttached()
{
base.OnAttached();
AssociatedObject.Loaded += OnLoaded;
}
private void OnLoaded(object sender, RoutedEventArgs e)
{
content = (UIElement)AssociatedObject.Content;
content.MouseLeftButtonDown += OnMouseLeftButtonDown;
content.MouseMove += OnMouseMove;
content.MouseLeftButtonUp += OnMouseLeftButtonUp;
}
private void OnMouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
content.CaptureMouse();
AssociatedObject.Cursor = Cursors.Hand;
scrollMousePoint = e.GetPosition(AssociatedObject);
scrollHorizontalOffset = AssociatedObject.HorizontalOffset;
scrollVerticalOffset = AssociatedObject.VerticalOffset;
}
private void OnMouseMove(object sender, System.Windows.Input.MouseEventArgs e)
{
if (content.IsMouseCaptured)
{
var newVerticalOffset = scrollVerticalOffset + (scrollMousePoint.Y - e.GetPosition(AssociatedObject).Y);
var newHorizontalOffset = scrollHorizontalOffset + (scrollMousePoint.X - e.GetPosition(AssociatedObject).X);
AssociatedObject.ScrollToVerticalOffset(newVerticalOffset);
AssociatedObject.ScrollToHorizontalOffset(newHorizontalOffset);
}
}
private void OnMouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
content.ReleaseMouseCapture();
AssociatedObject.Cursor = Cursors.Arrow;
}
}
}

示例用法:

<ScrollViewer
HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Auto">
<i:Interaction.Behaviors>
<local:ScrollViewerPanBehavior />
</i:Interaction.Behaviors>
<local:ZoomBorder
HorizontalAlignment="Center"
VerticalAlignment="Center">
<Grid>
<Image Source="ThumbsUp.png" />
</Grid>
</local:ZoomBorder>
</ScrollViewer>

这很有趣!

最新更新