【问题标题】:WPF DataGrid Zoom to mouse positionWPF DataGrid 缩放到鼠标位置
【发布时间】:2013-03-26 12:44:30
【问题描述】:

我有一个 DataGrid,它的 LayoutTransform 绑定到这样的 Slider:

<DataGrid.LayoutTransform>
            <ScaleTransform 
                ScaleX="{Binding ElementName=MySlider, Path=Value}"
                ScaleY="{Binding ElementName=MySlider, Path=Value}" />
        </DataGrid.LayoutTransform>
    </DataGrid>

    <Slider x:Name="MySlider"
            Minimum="0.3"
            Maximum="2.0"
            SmallChange="0.1"
            LargeChange="0.1"
            Value="1.0" 
            IsSnapToTickEnabled="True"
            TickFrequency="0.1"
            TickPlacement="TopLeft"
            VerticalAlignment="Bottom"
            HorizontalAlignment="Right"
            Width="200"
            Margin="0,0,61,0"  />

    <TextBlock Name="Lstate"
               Text="{Binding ElementName=MySlider, Path=Value, StringFormat={}{0:P0}}"
               VerticalAlignment="Bottom"
               HorizontalAlignment="Right"
               Width="50" Height="20"
               Margin="0,0,0,1" />

现在,在代码中,我有 PreviewMouseWheel 事件,代码如下:

bool handle = (Keyboard.Modifiers & ModifierKeys.Control) > 0;
        if (!handle)
            return;

        double value;

        if (e.Delta > 0)
            value = 0.1;
        else
            value = -0.1;

        MySlider.Value += value;

我的问题是:如何像 AutoCad 或其他程序一样滚动到实际的鼠标位置?

谢谢

对不起,我的英语不好......

【问题讨论】:

    标签: wpf datagrid mouse zooming


    【解决方案1】:

    我现在有一个非常非常好的解决方案:

    VirtualizingStackPanel.IsVirtualizing="True" 
    VirtualizingStackPanel.VirtualizationMode="Standard"
    EnableColumnVirtualization="False"
    EnableRowVirtualization="True"
    ScrollViewer.CanContentScroll="True"
    
        private void Data_OnPreviewMouseWheel(object sender, MouseWheelEventArgs e)
        {
            // Scroll to Zoom
            if (Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl))
            {
                // Prevent scroll
                e.Handled = true;
    
                var scrollview = FindVisualChild<ScrollViewer>(Data);
                if (scrollview != null)
                {  
                    // The "+20" are there to account for the scrollbars... i think. Not perfectly accurate.
                    var relativeMiddle = new Point((Data.ActualWidth + 20) / 2 + (Mouse.GetPosition(Data).X - Data.ActualWidth / 2), (Data.ActualHeight + 20) / 2 + (Mouse.GetPosition(Data).Y - Data.ActualHeight / 2));
                    var oldLocation = Data.LayoutTransform.Transform(Data.PointFromScreen(relativeMiddle));
    
                    // Zoom
                    MySlider.Value += (e.Delta > 0) ? MySlider.TickFrequency : -MySlider.TickFrequency;
    
                    // Scroll
                    var newLocation = Data.LayoutTransform.Transform(Data.PointFromScreen(relativeMiddle));
    
                    // Calculate offset
                    var shift = newLocation - oldLocation;
    
                    if (scrollview.CanContentScroll)
                    {
                        // Scroll to the offset (Item)
                        scrollview.ScrollToVerticalOffset(scrollview.VerticalOffset + shift.Y / scrollview.ViewportHeight);
                    }
                    else
                    {
                        // Device independent Pixels
                        scrollview.ScrollToVerticalOffset(scrollview.VerticalOffset + shift.Y);
                    }
    
                    // Device independent Pixels
                    scrollview.ScrollToHorizontalOffset(scrollview.HorizontalOffset + shift.X);
                }
            }
        }
    

    无论是否使用虚拟化,它都会缩放到 Datagrid 上的鼠标位置。

    【讨论】:

      猜你喜欢
      • 2020-05-28
      • 2015-04-20
      • 2018-03-07
      • 2014-04-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-11
      相关资源
      最近更新 更多