我正在制作一个带有地图图像的wpf应用程序,用户应该能够缩放和平移图像。还有一个矩形形状(在运行时创建)的集合,这些形状显示在国家名称上并且可以单击。
我将图像拉伸属性当前设置为“无”,因为如果将其设置为统一形状,则初始形状位置将与图像上的城市名称不匹配。如果将“拉伸”设置为“均匀”,如何修改形状的起始位置?
如果我和形状集合是Grid元素中的单独元素,如何实现平移?
如何确定在MouseLeftButtonDown处理程序中单击了哪些形状?
这是我的xaml
<Window x:Class="IMAGETRANSFORM.ShellView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:cal="http://www.caliburnproject.org"
WindowState="Maximized"
cal:Message.Attach="[Event MouseWheel] = [Action OnMouseWheel($source, $eventArgs)]">
<Grid>
<Image Source="{Binding imgsource}"
Stretch="None" HorizontalAlignment="Left" VerticalAlignment="Top">
<Image.RenderTransform>
<ScaleTransform x:Name="scale"
ScaleX="{Binding ZoomScale}"
ScaleY="{Binding ZoomScale}"
CenterX="0.0" CenterY="0.0"></ScaleTransform>
</Image.RenderTransform>
</Image>
<ItemsControl ItemsSource="{Binding RectItems}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas>
<Canvas.RenderTransform>
<ScaleTransform
ScaleX="{Binding ZoomScale}"
ScaleY="{Binding ZoomScale}"
CenterX="0.0" CenterY="0.0" />
</Canvas.RenderTransform>
</Canvas>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="Canvas.Left" Value="{Binding X}"/>
<Setter Property="Canvas.Top" Value="{Binding Y}"/>
</Style>
</ItemsControl.ItemContainerStyle>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Rectangle Width="{Binding Width}"
Height="{Binding Height}"
Fill="Transparent"
Stroke="Black" StrokeThickness="3"
cal:Message.Attach="[Event MouseLeftButtonDown] = [Action ShapeClicked($source, $eventArgs)]">
</Rectangle>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</Window>
这是我的viewmodel CS代码
using System;
using System.Collections.ObjectModel;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace IMAGETRANSFORM
{
public class RectItem
{
public double X { get; set; }
public double Y { get; set; }
public double Width { get; set; }
public double Height { get; set; }
}
public class ShellViewModel : Caliburn.Micro.PropertyChangedBase, IShell
{
private BitmapImage _imgsrc;
public BitmapImage imgsource
{
get { return _imgsrc; }
set { _imgsrc = value; NotifyOfPropertyChange(() => imgsource); }
}
private double _zoomscale;
public double ZoomScale
{
get { return _zoomscale; }
set { _zoomscale = value; NotifyOfPropertyChange(() => ZoomScale); }
}
public ObservableCollection<RectItem> RectItems { get; set; }
public ShellViewModel()
{
ZoomScale = 1.0;
RectItems = new ObservableCollection<RectItem>();
RectItem ri = new RectItem();
ri.X = 290;
ri.Y = 130;
ri.Height = 36;
ri.Width = 127;
RectItems.Add(ri);
BitmapImage bi = new BitmapImage();
bi.BeginInit();
bi.UriSource = new Uri(@"D:\EMap.png");
bi.EndInit();
imgsource = bi;
}
public void ShapeClicked(object sender, MouseButtonEventArgs e)
{
Rectangle r = sender as Rectangle;
double x = Canvas.GetLeft(r);
double y = Canvas.GetTop(r);
}
public void OnMouseWheel(object sender, MouseWheelEventArgs e)
{
if (e.Delta > 0)
{
//scrolled up...
ZoomScale += ZoomScale * 0.1;
}
else if (e.Delta < 0)
{
//scrolled down...
ZoomScale -= ZoomScale * 0.1;
}
}
}
}
答案 0 :(得分:0)
有很多方法可以做到这一点,但是基本上您应该缩放画布,而不是单个元素。如果您需要完整的工作示例,请查看my Perfy application,该示例显示了画布上可缩放和可滚动的元素。您要查找的内容的核心是MainWindow.xaml文件,该文件基本上可以归结为:
<ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<ItemsControl ItemsSource="{Binding CanvasItems}">
<ItemsControl.LayoutTransform>
<ScaleTransform ScaleX="{Binding Zoom}" ScaleY="{Binding Zoom}" />
</ItemsControl.LayoutTransform>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style TargetType="{x:Type ContentPresenter}">
<Setter Property="Canvas.Left" Value="{Binding X}" />
<Setter Property="Canvas.Top" Value="{Binding Y}" />
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
</ScrollViewer>
请注意,我已经删除了原始代码中用于调整RenderTransform的部分,因为该部分仅用于水平翻转整个画布。 ItemControl的LayoutTransform负责缩放。
您还询问了如何检测鼠标单击的元素。有几种方法可以做到这一点,但是我通常给每个画布元素一个自己的包含ICommand处理程序的视图模型,然后将一个行为添加到该元素的模板中以在单击时调用它(请参阅原始代码中的behaviors:MouseCaptureBehavior)。