2017-09-26 20 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

私は気にしないことを願っていますが、あなたのコードに基づいて、MVVMパターンに固執しようとする人々のための「行動」の形で回答を追加しました。 –

+0

@BradleyUffner私はまったく気にしません。 )さまざまな良い解決策が全体として役立ちます。私はあなたの投稿に言及した方法に満足しています;) – grek40

3

私は@ Grek40のコードをとり、MVVMパターンに固執しようとしている人のためにBehaviorに変換しました。もしあなたがこれに投票したら、彼の答えにも投票することを忘れないでください。 BehaviorベースクラスにSystem.Windows.Interactivity.WPFナゲットパッケージ (または他のフレームワーク)が必要です。これは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'プロパティ、' TransformMode'プロパティを通して 'RenderTranform'や' LayoutTransform'として変換が行われるかどうかを制御する機能を提供します。デフォルトでは 'RenderTransform'になっていますが、' Behavior'をスクロールビューア内に配置し、 'LayoutTransform'に設定すると、ズームインするとスクロールバーが表示されます。 –