【问题标题】:ScrollViewer is not working in WPF WindowsFormHostScrollViewer 在 WPF WindowsFormsHost 中不起作用
【发布时间】:2012-12-29 10:02:21
【问题描述】:

我的 WPF 表单中有带有 RichTextBox 的 WindowsFormHost,我已经为该 WindowsFormHost 提供了 ScrollViewer,但它不起作用,WindowsFormHost 超出了 ScrollViewer...

我的 XAML 是..

<ScrollViewer Background="DarkOrange" VerticalScrollBarVisibility="Auto" Height="80" MaxHeight="85" Margin="11,243,12,218" Width="756">
        <Canvas Height="100" Name="canvas1" Width="auto" >
            <WindowsFormsHost ClipToBounds="True" Height="120" Width="715" Margin="10,5,0,0" Name="winHostTEst" Background="Gray">
                <wf:RichTextBox BackColor="Cornsilk" Text="RichTextBox" x:Name="richTbTest" BorderStyle="None" Enabled="True" ForeColor="Black" Width="550" Multiline="True" ReadOnly="True" />
            </WindowsFormsHost>
        </Canvas>
    </ScrollViewer>

这是解决此问题的两个链接,但我无法实现。请查看这些链接并解决我的问题..

链接是:

http://blogs.msdn.com/b/ryanvog/archive/2009/01/20/clipping-legacy-content-hosted-inside-a-wpf-scrolling-region.aspx

http://www.mycsharp.de/wbb2/thread.php?threadid=76625

提前谢谢..

【问题讨论】:

    标签: wpf scrollviewer windowsformshost


    【解决方案1】:

    终于解决了

    在您的解决方案中为上述问题创建这个类,并使用新的类控件 (ScrollViewerWindowsFormsHost) 而不是 WindowsFormsHost

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Diagnostics;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms.Integration;
    using System.Windows.Media;
    using System.Runtime.InteropServices;
    using System.Windows;
    using System.Windows.Controls;
    
    namespace WPFRichTextBox
    {
    class ScrollViewerWindowsFormsHost: WindowsFormsHost
    {
    
        protected override void OnWindowPositionChanged(Rect rcBoundingBox)
        {
            base.OnWindowPositionChanged(rcBoundingBox);
    
            if (ParentScrollViewer == null)
                return;
    
            GeneralTransform tr = ParentScrollViewer.TransformToAncestor(MainWindow);
            var scrollRect = new Rect(new Size(ParentScrollViewer.ViewportWidth, ParentScrollViewer.ViewportHeight));
            scrollRect = tr.TransformBounds(scrollRect);
    
            var intersect = Rect.Intersect(scrollRect, rcBoundingBox);
            if (!intersect.IsEmpty)
            {
                tr = MainWindow.TransformToDescendant(this);
                intersect = tr.TransformBounds(intersect);
            }
    
            SetRegion(intersect);
        }
    
        protected override void OnVisualParentChanged(DependencyObject oldParent)
        {
            base.OnVisualParentChanged(oldParent);
            ParentScrollViewer = null;
    
            var p = Parent as FrameworkElement;
            while (p != null)
            {
                if (p is ScrollViewer)
                {
                    ParentScrollViewer = (ScrollViewer)p;
                    break;
                }
    
                p = p.Parent as FrameworkElement;
            }
        }
    
        private void SetRegion(Rect intersect)
        {
            using (var graphics = System.Drawing.Graphics.FromHwnd(Handle))
                SetWindowRgn(Handle, (new System.Drawing.Region(ConvertRect(intersect))).GetHrgn(graphics), true);
        }
    
        static System.Drawing.RectangleF ConvertRect(Rect r)
        {
            return new System.Drawing.RectangleF((float)r.X, (float)r.Y, (float)r.Width, (float)r.Height);
        }
    
        private Window _mainWindow;
        Window MainWindow
        {
            get
            {
                if (_mainWindow == null)
                    _mainWindow = Window.GetWindow(this);
    
                return _mainWindow;
            }
        }
    
        ScrollViewer ParentScrollViewer { get; set; }
    
        [DllImport("User32.dll", SetLastError = true)]
        public static extern int SetWindowRgn(IntPtr hWnd, IntPtr hRgn, bool bRedraw);
    }
    

    }

    XAML 代码:

    <Window x:Class="WPFRichTextBox.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
        xmlns:swfh="clr-namespace:WPFRichTextBox"
        Title="MainWindow" Height="600" Width="800" Background="LightBlue">
    <Grid Loaded="Grid_Loaded">
    
        <ScrollViewer  Background="DarkOrange" VerticalScrollBarVisibility="Auto" Height="100"  Margin="11,160,12,301" Width="756" Name="scrollViewer1">
            <Canvas Height="200" Name="canvas1" Width="auto" >
          <swfh:ScrollableWindowsFormsHost ClipToBounds="True" Height="194" Width="715" Margin="10,5,0,0" Background="Gray">
                    <wf:RichTextBox BackColor="Cornsilk" Text="RichTextBox" x:Name="richTbTest" BorderStyle="None" Enabled="True" ForeColor="Black" Width="550" Multiline="True" ReadOnly="True" />
          </swfh:ScrollableWindowsFormsHost>
            </Canvas>
        </ScrollViewer>
    </Grid>
    

    【讨论】:

    • 我在没有父 ScrollViewer 的情况下使用它,但它很棒并且解决了我的问题。我想知道你怎么没有得到任何功劳:)
    • 谢谢它帮了我很多。我知道我迟到了,但您可能想添加一种方法来管理可能导致尺寸不正确的 dpi 因素
    • 我用 Window.GetWindow(this) 替换了对 MainWindow 的引用,但除此之外我认为这非常好。谢谢!
    • 如果您的 WindowsFormsHost 被放置在 UserControl 中,那么答案可能不起作用。请参阅 [下文] (stackoverflow.com/a/37226886/1977871) 进行调整以实现该工作。
    • 就我而言,我需要使用VisualTreeHelper.GetParent() 来获取ScrollContentPresenter。然后您可以访问ScrollContentPresenter.ScrollOwner 属性以获取ScrollViewer。同样,@Marlon 似乎也需要一种不同的方法来获取 `ScrollViewer1。
    【解决方案2】:

    以防万一其他人有我的边缘情况,我在 WPF UserControl 中托管了一个 WinForms UserControl,它本身托管在一个 WinForms 表单中(不要问...) - Avinash 提供的类没有修复我的剪辑问题。

    但是在某处的某个论坛帖子上有一个修改版本,它起到了作用 - 所以我想我会在这里发布它以方便起见。

    class WindowsFormsHostEx : WindowsFormsHost
    {
        private PresentationSource _presentationSource;
    
        public WindowsFormsHostEx()
        {
            PresentationSource.AddSourceChangedHandler(this, SourceChangedEventHandler);
        }
    
        protected override void OnWindowPositionChanged(Rect rcBoundingBox)
        {
            base.OnWindowPositionChanged(rcBoundingBox);
    
            if (ParentScrollViewer == null)
                return;
    
            GeneralTransform tr = RootVisual.TransformToDescendant(ParentScrollViewer);
            var scrollRect = new Rect(new Size(ParentScrollViewer.ViewportWidth, ParentScrollViewer.ViewportHeight));
    
            var intersect = Rect.Intersect(scrollRect, tr.TransformBounds(rcBoundingBox));
            if (!intersect.IsEmpty)
            {
                tr = ParentScrollViewer.TransformToDescendant(this);
                intersect = tr.TransformBounds(intersect);
            }
            else
                intersect = new Rect();
    
            int x1 = (int)Math.Round(intersect.Left);
            int y1 = (int)Math.Round(intersect.Top);
            int x2 = (int)Math.Round(intersect.Right);
            int y2 = (int)Math.Round(intersect.Bottom);
    
            SetRegion(x1, y1, x2, y2);
        }
    
        protected override void Dispose(bool disposing)
        {
            base.Dispose(disposing);
    
            if (disposing)
                PresentationSource.RemoveSourceChangedHandler(this, SourceChangedEventHandler);
        }
    
        private void SourceChangedEventHandler(Object sender, SourceChangedEventArgs e)
        {
            ParentScrollViewer = FindParentScrollViewer();
        }
    
        private ScrollViewer FindParentScrollViewer()
        {
            DependencyObject vParent = this;
            ScrollViewer parentScroll = null;
            while (vParent != null)
            {
                parentScroll = vParent as ScrollViewer;
                if (parentScroll != null)
                    break;
    
                vParent = LogicalTreeHelper.GetParent(vParent);
            }
            return parentScroll;
        }
    
        private void SetRegion(int x1, int y1, int x2, int y2)
        {
            SetWindowRgn(Handle, CreateRectRgn(x1, y1, x2, y2), true);
        }
    
        private Visual RootVisual
        {
            get
            {
                if (_presentationSource == null)
                    _presentationSource = PresentationSource.FromVisual(this);
    
                return _presentationSource.RootVisual;
            }
        }
    
        private ScrollViewer ParentScrollViewer { get; set; }
    
        [DllImport("User32.dll", SetLastError = true)]
        static extern int SetWindowRgn(IntPtr hWnd, IntPtr hRgn, bool bRedraw);
    
        [DllImport("gdi32.dll")]
        static extern IntPtr CreateRectRgn(int nLeftRect, int nTopRect, int nRightRect, int nBottomRect);
    }
    

    【讨论】:

    • 这有一个缺点 - 托管控件的滚动不如标准 WindowsFormsHost 平滑。除此之外,它还有效。
    • 这对我有用,而接受的解决方案却没有。具体来说,我在滚动区域的 WPF UserControl 中托管了一个 winforms 控件。
    【解决方案3】:

    我发现 Marlon 的答案是最好的,但是如果用户有不同的 DPI 设置,它根本不起作用。 这是 Marlon 的答案,但解决了 DPI 的缩放问题。 我还添加了一个位置更改事件,因为我需要与滚动查看器中的 WindowsFormsHost 一起移动位于 WindowsFormsHost 内容顶部的弹出窗口。

    #region Using Declarations
    
    using System;
    using System.Runtime.InteropServices;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Forms.Integration;
    using System.Windows.Media;
    
    #endregion
    
    public class WindowsFormsHostEx : WindowsFormsHost
    {
        #region DllImports
        [DllImport("User32.dll", SetLastError = true)]
        static extern int SetWindowRgn(IntPtr hWnd, IntPtr hRgn, bool bRedraw);
    
        [DllImport("gdi32.dll")]
        static extern IntPtr CreateRectRgn(int nLeftRect, int nTopRect, int nRightRect, int nBottomRect);
    
        #endregion
    
        #region Events
        public event EventHandler LocationChanged;
        #endregion
    
        #region Members
        private PresentationSource _presentationSource;
        #endregion
    
        #region Properties
        private ScrollViewer ParentScrollViewer { get; set; }
        private bool Scrolling { get; set; }
        public bool Resizing { get; set; }
        private Visual RootVisual
        {
            get
            {
                _presentationSource = PresentationSource.FromVisual(this);
                return _presentationSource.RootVisual;
            }
        }
        #endregion
    
        #region Constructors
        public WindowsFormsHostEx()
        {
            PresentationSource.AddSourceChangedHandler(this, SourceChangedEventHandler);
        }
        #endregion
    
        #region Methods
    
        protected override void OnWindowPositionChanged(Rect rcBoundingBox)
        {
            DpiScale dpiScale = VisualTreeHelper.GetDpi(this);
    
            base.OnWindowPositionChanged(rcBoundingBox);
    
            Rect newRect = ScaleRectDownFromDPI(rcBoundingBox, dpiScale);
            Rect finalRect;
            if (ParentScrollViewer != null)
            {
                ParentScrollViewer.ScrollChanged += ParentScrollViewer_ScrollChanged;
                ParentScrollViewer.SizeChanged += ParentScrollViewer_SizeChanged;
                ParentScrollViewer.Loaded += ParentScrollViewer_Loaded;
            }
    
            if (Scrolling || Resizing)
            {
                if (ParentScrollViewer == null)
                    return;
                MatrixTransform tr = RootVisual.TransformToDescendant(ParentScrollViewer) as MatrixTransform;
    
                var scrollRect = new Rect(new Size(ParentScrollViewer.ViewportWidth, ParentScrollViewer.ViewportHeight));
                var c = tr.TransformBounds(newRect);
    
                var intersect = Rect.Intersect(scrollRect, c);
                if (!intersect.IsEmpty)
                {
                    tr = ParentScrollViewer.TransformToDescendant(this) as MatrixTransform;
                    intersect = tr.TransformBounds(intersect);
                    finalRect = ScaleRectUpToDPI(intersect, dpiScale);
                }
                else
                    finalRect = intersect = new Rect();
    
                int x1 = (int)Math.Round(finalRect.X);
                int y1 = (int)Math.Round(finalRect.Y);
                int x2 = (int)Math.Round(finalRect.Right);
                int y2 = (int)Math.Round(finalRect.Bottom);
    
                SetRegion(x1, y1, x2, y2);
                this.Scrolling = false;
                this.Resizing = false;
    
            }
            LocationChanged?.Invoke(this, new EventArgs());
        }
    
        private void ParentScrollViewer_Loaded(object sender, RoutedEventArgs e)
        {
            this.Resizing = true;
        }
    
        private void ParentScrollViewer_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            this.Resizing = true;
        }
    
        private void ParentScrollViewer_ScrollChanged(object sender, ScrollChangedEventArgs e)
        {
            if (e.VerticalChange != 0 || e.HorizontalChange != 0 || e.ExtentHeightChange != 0 || e.ExtentWidthChange != 0)
                Scrolling = true;
        }
    
        protected override void Dispose(bool disposing)
        {
            base.Dispose(disposing);
    
            if (disposing)
            {
                PresentationSource.RemoveSourceChangedHandler(this, SourceChangedEventHandler);
                _presentationSource = null;
            }
        }
    
        private void SourceChangedEventHandler(Object sender, SourceChangedEventArgs e)
        {
            if (ParentScrollViewer != null)
            {
                ParentScrollViewer.ScrollChanged -= ParentScrollViewer_ScrollChanged;
                ParentScrollViewer.SizeChanged -= ParentScrollViewer_SizeChanged;
                ParentScrollViewer.Loaded -= ParentScrollViewer_Loaded;
            }
            ParentScrollViewer = FindParentScrollViewer();
        }
    
        private ScrollViewer FindParentScrollViewer()
        {
            DependencyObject vParent = this;
            ScrollViewer parentScroll = null;
            while (vParent != null)
            {
                parentScroll = vParent as ScrollViewer;
                if (parentScroll != null)
                    break;
    
                vParent = LogicalTreeHelper.GetParent(vParent);
            }
            return parentScroll;
        }
    
        private void SetRegion(int x1, int y1, int x2, int y2)
        {
            SetWindowRgn(Handle, CreateRectRgn(x1, y1, x2, y2), true);
        }
    
        public static  Rect ScaleRectDownFromDPI(Rect _sourceRect, DpiScale dpiScale)
        {
            double dpiX = dpiScale.DpiScaleX;
            double dpiY = dpiScale.DpiScaleY;
            return new Rect(new Point(_sourceRect.X / dpiX, _sourceRect.Y / dpiY), new System.Windows.Size(_sourceRect.Width / dpiX, _sourceRect.Height / dpiY));
        }
    
        public static Rect ScaleRectUpToDPI(Rect _toScaleUp, DpiScale dpiScale)
        {
            double dpiX = dpiScale.DpiScaleX;
            double dpiY = dpiScale.DpiScaleY;
            return new Rect(new Point(_toScaleUp.X * dpiX, _toScaleUp.Y * dpiY), new System.Windows.Size(_toScaleUp.Width * dpiX, _toScaleUp.Height * dpiY));
        }
        #endregion
    }
    

    【讨论】:

      【解决方案4】:

      我们使用了多个ScrollViewers 和一个ViewBox,因此上述解决方案均不适合我们。所以这是我们的解决方案,它也可以处理不同的 DPI 设置。

      using System;
      using System.Collections.Generic;
      using System.Linq;
      using System.Runtime.InteropServices;
      using System.Windows;
      using System.Windows.Controls;
      using System.Windows.Forms.Integration;
      using System.Windows.Media;
      using System.Windows.Threading;
      
      
      namespace XYZ
      {
      
          public class ClippingWindowsFormsHost : WindowsFormsHost
          {
              private readonly DispatcherTimer _updateTimer;
      
              private Rect _bounds;
      
              private PresentationSource _source;
      
              public ClippingWindowsFormsHost()
              {
                  PresentationSource.AddSourceChangedHandler(this, _sourceChangedEventHandler);
      
                  _updateTimer = new DispatcherTimer(DispatcherPriority.Render);
                  _updateTimer.Tick += _updateTick;
                  _updateTimer.Interval = TimeSpan.FromMilliseconds(100);
              }
      
              private void _updateTick(object sender, EventArgs e)
              {
                  _updateTimer.Stop();
      
                  if (_source == null)
                      return;
      
      
                  // Get the Rect of the scrollviewer on screen.
                  Rect scrollRect = _getScrollRect();
      
                  // apply dpi settings
                  scrollRect = _scaleDpi(scrollRect);
      
                  if (scrollRect.Width > 0 && scrollRect.Height > 0) // if the rect is valid...
                  {
                      int x1 = (int) Math.Ceiling(scrollRect.X);
                      int y1 = (int) Math.Ceiling(scrollRect.Y);
                      int x2 = (int) Math.Ceiling(scrollRect.Right);
                      int y2 = (int) Math.Ceiling(scrollRect.Bottom);
      
                      SetWindowRgn(Handle, CreateRectRgn(x1, y1, x2, y2), true);
                  }
                  else
                      SetWindowRgn(Handle, CreateRectRgn(0, 0, 0, 0), true);
      
              }
      
              private Rect _scaleDpi(Rect rect)
              {
                  if (_source.CompositionTarget != null)
                  {
                      Matrix transformToDevice = _source.CompositionTarget.TransformToDevice;
                      if (!transformToDevice.IsIdentity)
                      {
                          Point scaledSize = transformToDevice.Transform(new Point(rect.Width, rect.Height));
                          rect = new Rect(rect.X, rect.Y, scaledSize.X, scaledSize.Y);
                      }
                  }
      
                  return rect;
              }
      
              [DllImport("User32.dll", SetLastError = true)]
              private static extern int SetWindowRgn(IntPtr hWnd, IntPtr hRgn, bool bRedraw);
      
              [DllImport("gdi32.dll")]
              private static extern IntPtr CreateRectRgn(int nLeftRect, int nTopRect, int nRightRect, int nBottomRect);
      
              protected override void OnWindowPositionChanged(Rect rcBoundingBox)
              {
                  base.OnWindowPositionChanged(rcBoundingBox);
                  _updateClipping(rcBoundingBox);
              }
      
              private void _updateClipping(Rect bounds)
              {
                  if (_source == null || _bounds == bounds)
                      return;
      
                  _bounds = bounds;
      
                  // Only update clipping in certain intervals, otherwise splitpanels can create huge cpu load
                  _updateTimer.Stop();
                  _updateTimer.Start();
              }
      
              private Rect _getScrollRect()
              {
                  ScrollViewer scrollViewer = _getTopScrollViewer();
      
                  // Get the screenposition of the scrollviewer
                  Point topLeft = scrollViewer.PointToScreen(new Point(0, 0));
                  Point bottomRight = scrollViewer.PointToScreen(new Point(scrollViewer.ViewportWidth, scrollViewer.ViewportHeight));
      
                  Rect scrollRect = new Rect(topLeft, bottomRight);
      
      
      
                  // Get "this" position and use it to offset the scrollrect
                  // because that is basically the scrolled distance
                  Point myPosition = PointToScreen(new Point());
                  scrollRect.Offset(-myPosition.X, -myPosition.Y);
      
                  return scrollRect;
              }
      
              private ScrollViewer _getTopScrollViewer()
              {
                  DependencyObject parent = this;
                  ScrollViewer lastViewer = null;
                  while ((parent = VisualTreeHelper.GetParent(parent)) != null)
                  {
                      ScrollViewer viewer = parent as ScrollViewer;
                      if (viewer != null)
                          lastViewer = viewer;
                  }
      
                  return lastViewer;
              }
      
              protected override void Dispose(bool disposing)
              {
                  base.Dispose(disposing);
      
                  if (disposing)
                  {
                      _updateTimer.Stop();
                      PresentationSource.RemoveSourceChangedHandler(this, _sourceChangedEventHandler);
                  }
              }
      
              private void _sourceChangedEventHandler(object sender, SourceChangedEventArgs e)
              {
                  _updateTimer.Stop();
                  _source = e.NewSource;
              }
          }
      }
      

      【讨论】:

        【解决方案5】:

        如果要将您的 WindowsFormsHost 放置在 UserControl 中,则 answer presented by Avinash 可能不起作用。所以我不得不调整 ScrollViewerWindowsFormsHost 类如下。

            public class ScrollViewerWindowsFormsHost : WindowsFormsHost
            {
                protected override void OnWindowPositionChanged(Rect rcBoundingBox)
                {
                    base.OnWindowPositionChanged(rcBoundingBox);
        
                    if (ParentScrollViewer == null)
                        //return; // Instead, you set the ParentScrollViewr by calling the following method.
                        SetParentScrollViewer();
        
                    GeneralTransform tr = ParentScrollViewer.TransformToAncestor(MainWindow);
        
                    var scrollRect = new Rect(new Size(ParentScrollViewer.ViewportWidth, ParentScrollViewer.ViewportHeight));
                    scrollRect = tr.TransformBounds(scrollRect);
        
                    var intersect = Rect.Intersect(scrollRect, rcBoundingBox);
                    if (!intersect.IsEmpty)
                    {
                        tr = MainWindow.TransformToDescendant(this);
                        intersect = tr.TransformBounds(intersect);
                    }
        
                    SetRegion(intersect);
                }
        
                // This is new a new method. This is called from the above method.
                private void SetParentScrollViewer()
                {
                    if (ParentScrollViewer is ScrollViewer)
                        return; // that means its already set;
        
                    var p = Parent as FrameworkElement;
                    while (p != null)
                    {
                        if (p is ScrollViewer)
                        {
                            ParentScrollViewer = (ScrollViewer)p;
                            break;
                        }
        
                        p = p.Parent as FrameworkElement;
                    }
                }
                // Just comment out this method, you dont need this any more. You set the parent Scroll Viewer by calling SetParentScrollViewer Method.
                //protected override void OnVisualParentChanged(DependencyObject oldParent)
                //{
                //    base.OnVisualParentChanged(oldParent);
                //    ParentScrollViewer = null;
        
                //    var p = Parent as FrameworkElement;
                //    while (p != null)
                //    {
                //        if (p is ScrollViewer)
                //        {
                //            ParentScrollViewer = (ScrollViewer)p;
                //            break;
                //        }
        
                //        p = p.Parent as FrameworkElement;
        
                //    }
                //}
        
                private void SetRegion(Rect intersect)
                {
                    using (var graphics = System.Drawing.Graphics.FromHwnd(Handle))
                        SetWindowRgn(Handle, (new System.Drawing.Region(ConvertRect(intersect))).GetHrgn(graphics), true);
                }
        
                static System.Drawing.RectangleF ConvertRect(Rect r)
                {
                    return new System.Drawing.RectangleF((float)r.X, (float)r.Y, (float)r.Width, (float)r.Height);
                }
        
                private Window _mainWindow;
                Window MainWindow
                {
                    get
                    {
                        if (_mainWindow == null)
                            _mainWindow = Window.GetWindow(this);
        
                        return _mainWindow;
                    }
                }
        
                ScrollViewer ParentScrollViewer { get; set; }
        
                [DllImport("User32.dll", SetLastError = true)]
                public static extern int SetWindowRgn(IntPtr hWnd, IntPtr hRgn, bool bRedraw);
            }
        

        就是这样。每件事都保持不变。

        【讨论】:

          【解决方案6】:

          那是因为 ScrollViewer 不知道它必须滚动。如果您的鼠标在 RichTextBox 上,它将拦截所有键。您可以继承 RichTextBox(即 WndProc)并侦听鼠标滚轮事件,然后使用 RaiseEvent 将它们发送到 scrollViewer。不要忘记 WndProc 在与 WPF 不同的线程上运行,因此您需要执行以下操作:

          案例 WM_MOUSEWHEEL: Dispatcher.BeginInvoke(new Action(() => VisualHelper.FindParent(richTextBox).RaiseEvent(..具有正确参数的鼠标滚轮事件..));

          【讨论】:

            猜你喜欢
            • 2011-08-03
            • 1970-01-01
            • 2016-05-26
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-01-03
            • 1970-01-01
            • 2012-03-02
            相关资源
            最近更新 更多