2017-09-26 205 views
0
<utils:ScrollViewer x:Name="ImageViewer" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto" Grid.Row="2"                 
             CurrentHorizontalOffset="{Binding ScrollHorizontalValue, Mode=TwoWay}" 
             CurrentVerticalOffset="{Binding ScrollVerticalValue, Mode=TwoWay}"           
             > 
        <i:Interaction.Triggers> 
         <i:EventTrigger EventName="PreviewMouseWheel"> 
          <cmd:EventToCommand Command="{Binding MouseWheelZoomCommand}" PassEventArgsToCommand="True"/> 
         </i:EventTrigger> 
         <i:EventTrigger EventName="ScrollChanged"> 
          <cmd:EventToCommand Command="{Binding ScrollChangedCommand}" PassEventArgsToCommand="True"/> 
         </i:EventTrigger> 
        </i:Interaction.Triggers> 
        <Grid Background="{StaticResource ThatchBackground}" RenderTransformOrigin="0.5,0.5"> 
         <ItemsControl ItemsSource="{Binding CanvasItems}" ItemTemplate="{StaticResource templateOfROI}"> 
          <ItemsControl.ItemsPanel> 
           <ItemsPanelTemplate> 
            <Canvas x:Name="BackPanel" 
             Width="{Binding DataContext.ImageWidth, ElementName=MainGrid}" 
             Height="{Binding DataContext.ImageHeight, ElementName=MainGrid}" 
             ClipToBounds="True"> 
             <Canvas.Background> 
              <ImageBrush x:Name="BackImage" 
                 ImageSource="{Binding DataContext.SelectedImage.Path, ElementName=MainGrid}"/> 
             </Canvas.Background> 

             <i:Interaction.Triggers> 
              <i:EventTrigger EventName="MouseRightButtonDown"> 
               <cmd:EventToCommand Command="{Binding DataContext.MouseRightCommand, ElementName=MainGrid}"/> 
              </i:EventTrigger> 
              <i:EventTrigger EventName="MouseLeftButtonDown"> 
               <cmd:EventToCommand Command="{Binding DataContext.MouseMoveStartCommand, ElementName=MainGrid}" PassEventArgsToCommand="True"/> 
              </i:EventTrigger> 
              <i:EventTrigger EventName="MouseMove"> 
               <cmd:EventToCommand Command="{Binding DataContext.MouseMovingCommand, ElementName=MainGrid}" PassEventArgsToCommand="True"/> 
              </i:EventTrigger> 
              <i:EventTrigger EventName="MouseRightButtonUp"> 
               <cmd:EventToCommand Command="{Binding DataContext.MouseMoveEndCommand, ElementName=MainGrid}"/> 
              </i:EventTrigger> 
              <i:EventTrigger EventName="MouseLeave"> 
               <cmd:EventToCommand Command="{Binding DataContext.MouseLeaveCommand, ElementName=MainGrid}"/> 
              </i:EventTrigger> 
             </i:Interaction.Triggers> 

             <Canvas.LayoutTransform> 
              <TransformGroup> 
               <ScaleTransform ScaleX="{Binding ScaleX}" 
                   ScaleY="{Binding ScaleY}"> 
               </ScaleTransform> 
             </TransformGroup> 
            </Canvas.LayoutTransform> 
           </Canvas> 
          </ItemsPanelTemplate> 
         </ItemsControl.ItemsPanel> 
        </ItemsControl> 
       </Grid> 
      </utils:ScrollViewer> 

参考点固定为左和顶点以放大画布。我想放大并缩小鼠标指针。我如何使它进入MVVM模式? (不在代码后面)。使用鼠标滚轮,我可以放大画布。我已经使用RenderTransformOrigin,CenterX,CenterY但它不起作用。我想我做了一个错误的方法。请帮我..WPF缩放帆布中心在鼠标位置

+1

哪里是你的代码,处理变焦?即使它没有像预期的那样工作,你仍然应该把它作为你目前的方法。 – grek40

回答

3

既然你没有提供当前的缩放代码,这里是缩放鼠标位置的一般示例:

<Grid x:Name="grid1" Background="White" MouseWheel="Grid_MouseWheel"> 
    <Grid x:Name="grid2"> 
     <Grid.RenderTransform> 
      <MatrixTransform/> 
     </Grid.RenderTransform> 
     <Rectangle Width="20" Height="20" Margin="20" VerticalAlignment="Top" HorizontalAlignment="Left" Fill="Green"/> 
    </Grid> 
</Grid> 

随着代码更新变换矩阵:

private void Grid_MouseWheel(object sender, MouseWheelEventArgs e) 
{ 
    var matTrans = grid2.RenderTransform as MatrixTransform; 
    var pos1 = e.GetPosition(grid1); 

    var scale = e.Delta > 0 ? 1.1 : 1/1.1; 

    var mat = matTrans.Matrix; 
    mat.ScaleAt(scale, scale, pos1.X, pos1.Y); 
    matTrans.Matrix = mat; 
    e.Handled = true; 
} 
+1

我希望你不介意,但我添加了一个答案,根据你的代码,在一个'Behavior'的形式为人们尽量坚持MVVM模式。 –

+0

@BradleyUffner我根本不介意。各种好的解决方案,从而帮助作为一个整体,我很乐意跟你提到我的贡献的方式更多) – grek40

3

我把@ Grek40的代码和把它转换到一个Behavior任何人试图坚持使用MVVM模式。如果你投票赞成,请记住也要投票赞成他的回答,因为我的工作基于他的工作。它需要用于Behavior基类的System.Windows.Interactivity.WPF NuGet包 (或一些其他的框架)。您可以将其应用于任何UIElement。它会自动为你添加MatrixTransform,所以你不必在XAML中这样做(它会覆盖任何现有的变换)。

public class ZoomOnMouseWheel : Behavior<FrameworkElement> 
{ 
    public Key? ModifierKey { get; set; } = null; 
    public TransformMode TranformMode { get; set; } = TransformMode.Render; 

    private Transform _transform; 

    protected override void OnAttached() 
    { 
     if (TranformMode == TransformMode.Render) 
     { 
      _transform = AssociatedObject.RenderTransform = new MatrixTransform(); 
     } 
     else 
     { 
      _transform = AssociatedObject.LayoutTransform = new MatrixTransform(); 
     } 

     AssociatedObject.MouseWheel += AssociatedObject_MouseWheel; 
    } 

    protected override void OnDetaching() 
    { 
     AssociatedObject.MouseWheel -= AssociatedObject_MouseWheel; 
    } 

    private void AssociatedObject_MouseWheel(object sender, MouseWheelEventArgs e) 
    { 
     if ((!ModifierKey.HasValue || !Keyboard.IsKeyDown(ModifierKey.Value)) && ModifierKey.HasValue) 
     { 
      return; 
     } 

     if (!(_transform is MatrixTransform transform)) 
     { 
      return; 
     } 

     var pos1 = e.GetPosition(AssociatedObject); 
     var scale = e.Delta > 0 ? 1.1 : 1/1.1; 
     var mat = transform.Matrix; 
     mat.ScaleAt(scale, scale, pos1.X, pos1.Y); 
     transform.Matrix = mat; 
     e.Handled = true; 
    } 
} 

public enum TransformMode 
{ 
    Layout, 
    Render, 
} 

您可以使用它像这样:

<Grid> 
    <interactivity:Interaction.Behaviors> 
     <behaviors:ZoomOnMouseWheel /> 
    </interactivity:Interaction.Behaviors> 
    <!--Your grid content here--> 
</Grid> 

不要忘了xmlns

xmlns:interactivity="http://schemas.microsoft.com/expression/2010/interactivity" 
+0

我已经添加了当修饰键,如'LeftCtrl'通过按住只有滚动的能力在'ModifierKey'属性,并且如果变换控制的能力被作为一个'RenderTranform'或'LayoutTransform'通过'TransformMode'属性来完成。它默认为'RenderTransform',但如果你把该元素与'Behavior'一个的ScrollViewer内,并将其设置为'LayoutTransform',您可以在放大得到滚动条。 –