【问题标题】:C# Winforms: PropertyGrid not updated when item added to CollectionC# Winforms:将项目添加到集合时,PropertyGrid 未更新
【发布时间】:2010-06-10 12:24:59
【问题描述】:

我有一个自定义类,可以通过PropertyGrid 进行编辑。在那个类中,我有一个自定义的Collection(带有自定义的PropertyDescriptorTypeConverter)。

可以使用默认的集合编辑器向Collection 添加或删除项目。这一切都很好。但是 - 关闭集合编辑器后,PropertyGrid 不会更新。当我在PropertyGrid 上手动调用Refresh() 时,更改会反映在PropertyGrid 中。

如何在集合编辑器关闭时让 PropertyGrid 自动刷新?我之前寻求过一个解决方案,我应该继承 CollectionEditor(我似乎找不到)。

请帮忙。

【问题讨论】:

    标签: c# collections propertygrid


    【解决方案1】:

    RefreshPropertiesAttribute 类

    表示属性网格 关联时应该刷新 属性值变化。这节课 不能继承。

    http://msdn.microsoft.com/en-us/library/system.componentmodel.refreshpropertiesattribute.aspx插入

    使用描述符添加属性

            Public Overrides ReadOnly Property Attributes() As System.ComponentModel.AttributeCollection
                Get
                    Return New AttributeCollection(New Attribute() {RefreshPropertiesAttribute.Repaint})
                End Get
            End Property
    

    演练:在设计时调试自定义 Windows 窗体控件http://msdn.microsoft.com/en-us/library/5ytx0z24.aspx

    【讨论】:

    • 我试过了,但还是不行。当我在集合中添加 1 个项目时,它是空的,PropertyGrid 得到更新。当我添加另一个项目时,在我手动刷新之前什么都不会发生......
    • 我以前也遇到过这种情况。问题出在你的课上。我建议调试控件的设计时间。
    • 我认为这与类型转换器convert-to有关
    【解决方案2】:

    您也可以尝试将 NotifyParentProperty 属性添加到集合中。这在类似情况下对我有用。

    【讨论】:

      【解决方案3】:

      我在这种情况下得到了解决方案。 需要从 CollectionEditor 类派生并制作这样的自定义编辑器:

      public class MeasuredParamEditor : CollectionEditor
      {
      
          public static EventHandler CollectionChanged;
      
          public MeasuredParamEditor(Type type)
              : base(type)
          { }
      
          protected override string GetDisplayText(object value)
          {
              if (value is MeasuredParam)
              {
                  MeasuredParam param = (MeasuredParam)value;
                  return string.Format("{0}: {1}", param.Name, param.Value);
              }
              else return base.GetDisplayText(value);
          }
      
          protected override CollectionForm CreateCollectionForm()
          {
              CollectionForm collectionForm = base.CreateCollectionForm();
              Form frm = collectionForm as Form;
              if (frm != null)
              {
                  // Get OK button of the Collection Editor...
                  Button button = frm.AcceptButton as Button;
                  // Handle click event of the button
                  button.Click += new EventHandler(OnCollectionChanged);
              }
              return collectionForm;
          }
      
          void OnCollectionChanged(object sender, EventArgs e)
          {
              if (CollectionChanged != null)
              {
                  CollectionChanged(sender, e);
              }
          }
      }
      

      在主窗体中,我订阅了自定义编辑器的静态事件。

          private void MainForm_Load(object sender, EventArgs e)
          {
                  MeasuredParamEditor.CollectionChanged += new EventHandler(OnMeasuredParamsChanged); 
          }
      
          private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
          {
              MeasuredParamEditor.CollectionChanged -= new EventHandler(OnMeasuredParamsChanged);
      
          }
      
          void OnMeasuredParamsChanged(object sender, EventArgs e)
          {
              this.myPropGrid.Refresh();
          }
      

      问候,阿尔乔姆

      【讨论】:

        【解决方案4】:

        我使用这个基类

        public class CollectionEditorBase : CollectionEditor
        {
            protected PropertyGrid ownerGrid;
        
            public CollectionEditorBase(Type type) : base(type) { }
        
            public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
            {
                PropertyInfo ownerGridProperty = provider.GetType().GetProperty("OwnerGrid", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
                ownerGrid = (PropertyGrid)ownerGridProperty.GetValue(provider);
        
                return base.EditValue(context, provider, value);
            }
        
            protected override CollectionForm CreateCollectionForm()
            {
                CollectionForm cf = base.CreateCollectionForm();
                cf.FormClosing += delegate(object sender, FormClosingEventArgs e)
                {
                    ownerGrid.Refresh();
        
                    if (CollectionEditorClosed != null)
                        CollectionEditorClosed(this, value);
                };
        
                return cf;
            }
        }
        

        然后,您只需在此基础上创建您的收藏编辑器。集合表单关闭时会自动刷新属性网格。

        但请注意,此解决方案正在反映到属性网格的内部,并且可以随时中断,但我已经这样做了一段时间了,没有任何问题

        【讨论】:

          【解决方案5】:

          完美解决方案

          using System;
          using System.ComponentModel.Design;
          using System.Windows.Forms;
          using System.Drawing.Design;
          using System.Collections;
          using System.ComponentModel;
          
          namespace ppgExpandableList
          {
              public class ExpandableListEditor : CollectionEditor
              {
                  public ExpandableListEditor(Type type) : base(type){}
                  public override object EditValue(ITypeDescriptorContext context,
                      System.IServiceProvider provider, object value)
                  {
                      object editedValue = base.EditValue(context, provider, value);
          
                      IList tmpList = (IList)editedValue;
                      object tmpValue = Activator.CreateInstance(value.GetType());
                      IList editedList = (IList)tmpValue;
          
                      foreach (object item in tmpList)
                      {
                          editedList.Add(item);
                      }
          
                      return editedList;
                  }
          
                  public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
                  {
                      return UITypeEditorEditStyle.Modal;
                  }
              }
          }
          

          【讨论】:

            猜你喜欢
            • 2016-04-29
            • 2011-05-25
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2020-11-05
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多