【问题标题】:How can I catch scroll events in windows forms PropertyGrid如何在 Windows 窗体 PropertyGrid 中捕获滚动事件
【发布时间】:2009-10-20 17:20:31
【问题描述】:

我正在尝试同步两个属性网格的垂直滚动条。这个想法是当用户滚动一个属性网格时,另一个属性网格滚动相同的量。

我的第一种方法是处理滚动事件,但 PropertyGrid 似乎不会生成这种事件。我查看了 PropertyGrid 中包含的控件,并且有一个 PropertyGridView,我敢打赌它是带有滚动条的控件。

有人知道实现我想要的解决方法吗?

谢谢。

【问题讨论】:

    标签: winforms propertygrid


    【解决方案1】:

    这个显示了与相邻的 PropertyGridView 的同步。请注意,您必须扩展它以处理用户单击任一控件。此版本更新 propertyGrid2 以匹配 propertyGrid1,但反之则不然。

    using System;
    using System.Windows.Forms;
    using System.Reflection;
    
    namespace WindowsApplication1
    {
        public partial class Form1 : Form
        {
            Control m_pgv_1 = null;
            Control m_pgv_2 = null;
            MethodInfo m_method_info;
    
            public Form1 ()
            {
                InitializeComponent ();
    
                // Set the Property Grid Object to something
                propertyGrid1.SelectedObject = dataGridView1;
                propertyGrid2.SelectedObject = dataGridView1;
    
                // Loop through sub-controlls and find PropertyGridView
                m_pgv_1 = FindControl (propertyGrid1.Controls, "PropertyGridView");
                m_pgv_2 = FindControl (propertyGrid2.Controls, "PropertyGridView");
    
                // Reflection trickery to get a private/internal field
                // and method, scrollBar and SetScrollOffset in this case
                Type type = m_pgv_1.GetType ();
                FieldInfo f = FindField (type, "scrollBar");
                m_method_info = FindMethod (type, "SetScrollOffset");
    
                // Get the scrollBar for our PropertyGrid and add the event handler
                ((ScrollBar)f.GetValue (m_pgv_1)).Scroll +=
                    new ScrollEventHandler (propertyGrid1_Scroll);
            }
    
            private void propertyGrid1_Scroll (object sender, ScrollEventArgs e)
            {
                System.Console.WriteLine ("Scroll");
    
                // Set the new scroll position on the neighboring
                // PropertyGridView
                object [] parameters = { e.NewValue };
                m_method_info.Invoke (m_pgv_2, parameters);
            }
    
            private static Control FindControl (
                Control.ControlCollection controls, string name)
            {
                foreach (Control c in controls)
                {
                    if (c.Text == name)
                        return c;
                }
    
                return null;
            }
    
            private static MethodInfo FindMethod (Type type, string method)
            {
                foreach (MethodInfo mi in type.GetMethods ())
                {
                    if (method == mi.Name)
                        return mi;
                }
    
                return null;
            }
    
            private static FieldInfo FindField (Type type, string field)
            {
                FieldInfo f = type.GetField (field,
                   BindingFlags.Instance | BindingFlags.NonPublic);
    
                return f;
            }
        }
    }
    

    【讨论】:

      【解决方案2】:

      这需要一点技巧,但应该这样做:

      using System;
      using System.Windows.Forms;
      using System.Reflection;
      
      namespace WindowsApplication1 {
          public partial class Form1 : Form {
              Control m_pgv = null;
      
              public Form1 () {
                  InitializeComponent ();
      
                  // Set the Property Grid Object to something
                  propertyGrid1.SelectedObject = dataGridView1;
      
                  // Loop through sub-controls and find PropertyGridView
                  foreach (Control c in propertyGrid1.Controls) {
                      if (c.Text == "PropertyGridView")
                      {
                          m_pgv = (Control)c;
                          break;
                      }
                  }
      
                  // Reflection trickery to get a private field,
                  // scrollBar in this case
                  Type t = m_pgv.GetType ();
                  FieldInfo f = t.GetField("scrollBar", 
                      BindingFlags.Instance | BindingFlags.NonPublic);
      
                  // Get the scrollBar for our PropertyGrid and add the event handler
                  ScrollBar sb = (ScrollBar) f.GetValue(m_pgv);
                  sb.Scroll +=  new ScrollEventHandler(propertyGrid1_Scroll);
              }
      
              private void propertyGrid1_Scroll (object sender, ScrollEventArgs e) {
                  System.Console.WriteLine ("Scroll");
              }
          }
      }
      

      【讨论】:

      • 你如何让另一个控件滚动以匹配第一个?
      • 使用这段代码我能够同步两个滚动条。当我移动一个时,另一个相应地移动。问题是内容不随滚动条滚动。我想最好还是放弃我原来的想法。
      • 您必须在相邻的 PropertyGridView 上调用 SetScrollPosition()。请参阅我的第二个答案。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多