2008-11-24 17 views
22

Làm thế nào để bạn sửa đổi một propertygrid khi chạy theo mọi cách? Tôi muốn để có thể thêm và loại bỏ các thuộc tính và thêm "các loại động", những gì tôi có nghĩa là với một loại mà kết quả trong một thời gian chạy tạo ra thả xuống trong propertygrid bằng cách sử dụng một TypeConverter.Làm thế nào để sửa đổi PropertyGrid khi chạy (thêm/xóa thuộc tính và kiểu động/enums)

Tôi thực sự có thể thực hiện cả hai điều đó (thêm/xóa thuộc tính và thêm loại động) nhưng chỉ riêng biệt không cùng một lúc.

Để thực hiện hỗ trợ thêm và xóa thuộc tính trong thời gian chạy, tôi đã sử dụng this codeproject article và sửa đổi mã một chút để hỗ trợ các loại khác nhau (không chỉ là chuỗi).

private System.Windows.Forms.PropertyGrid propertyGrid1; 
private CustomClass myProperties = new CustomClass(); 

public Form1() 
{ 
    InitializeComponent(); 

    myProperties.Add(new CustomProperty("Name", "Sven", typeof(string), false, true)); 
    myProperties.Add(new CustomProperty("MyBool", "True", typeof(bool), false, true)); 
    myProperties.Add(new CustomProperty("CaptionPosition", "Top", typeof(CaptionPosition), false, true)); 
    myProperties.Add(new CustomProperty("Custom", "", typeof(StatesList), false, true)); //<-- doesn't work 
} 

/// <summary> 
/// CustomClass (Which is binding to property grid) 
/// </summary> 
public class CustomClass: CollectionBase,ICustomTypeDescriptor 
{ 
    /// <summary> 
    /// Add CustomProperty to Collectionbase List 
    /// </summary> 
    /// <param name="Value"></param> 
    public void Add(CustomProperty Value) 
    { 
     base.List.Add(Value); 
    } 

    /// <summary> 
    /// Remove item from List 
    /// </summary> 
    /// <param name="Name"></param> 
    public void Remove(string Name) 
    { 
     foreach(CustomProperty prop in base.List) 
     { 
      if(prop.Name == Name) 
      { 
       base.List.Remove(prop); 
       return; 
      } 
     } 
    } 

vv ...

public enum CaptionPosition 
{ 
    Top, 
    Left 
} 

giải pháp hoàn chỉnh của tôi có thể được tải về here.

Nó hoạt động tốt khi tôi thêm chuỗi, bool hoặc enums, nhưng khi tôi cố gắng thêm một "loại động" như StatesList nó không hoạt động. Có ai biết tại sao và có thể giúp tôi giải quyết nó?

public class StatesList : System.ComponentModel.StringConverter 
{ 
    private string[] _States = { "Alabama", "Alaska", "Arizona", "Arkansas" }; 

    public override System.ComponentModel.TypeConverter.StandardValuesCollection 
    GetStandardValues(ITypeDescriptorContext context) 
    { 
     return new StandardValuesCollection(_States); 
    } 

    public override bool GetStandardValuesSupported(ITypeDescriptorContext context) 
    { 
     return true; 
    } 

    public override bool GetStandardValuesExclusive(ITypeDescriptorContext context) 
    { 
     return true; 
    } 
} 

Phương pháp sử dụng một TypeConverter hoạt động tốt khi bạn không cố gắng thêm tính tại thời gian chạy, ví dụ this code công trình mà không cần bất kỳ vấn đề, nhưng tôi muốn để có thể làm cả hai.

Hãy xem my project. Cảm ơn!

Trả lời

7

Bạn làm gì, đang thêm StatesList (một TypeConverter) làm thuộc tính.
Bạn nên làm gì, đang thêm thuộc tính với StatesList làm TypeConverter của nó.

5

Ah, tất nhiên!

myProperties.Add(new CustomProperty("Custom", "", typeof(States), false, true)); 

[TypeConverter(typeof(StatesList))] 
public class States 
{ 
} 

Làm việc như một sự quyến rũ, cảm ơn bạn!

Tôi đã cập nhật dự án của mình, hy vọng nó có thể hữu ích cho người khác, nó có thể được tìm thấy here.

+0

Bạn đang chào đón :) –

+0

Tôi biết bài này là rất cũ, nhưng tôi có một câu hỏi ngắn. Tôi sử dụng chính xác mã của bạn trong ứng dụng của tôi nhưng combobox tùy chỉnh không hoạt động. Tên của thuộc tính có màu xám và không có tùy chọn nào. Bất kỳ ý tưởng, những gì tôi có thể làm để sửa chữa điều đó? Xin cảm ơn trước, Martin – user653427

+1

@ user653427, Vì đây là một câu hỏi cũ nên bạn cũng nên đặt câu hỏi mới và liên kết lại trang này. Bạn sẽ có thể cung cấp thêm chi tiết và tiếp cận nhiều người hơn theo cách đó. –

3

Câu hỏi và câu trả lời này rất hữu ích đối với tôi. Tuy nhiên, tôi cần mở rộng thêm một chút bằng cách cho phép các giá trị danh sách thả xuống được tạo ra trong thời gian chạy. Tôi nghĩ rằng tôi sẽ đăng một số mã mẫu liên quan đến những gì nó cần thiết, trong trường hợp bất cứ ai tìm thấy nó hữu ích.

Đầu tiên, tôi đã thêm một tham số tùy chọn để các nhà xây dựng CustomProperty và thêm một tài sản Options:

private List<string> lOptions; 

    public CustomProperty(string sName, object value, Type tType, bool bReadOnly, bool bVisible, List<string> lOptions) 
    { 
     this.lOptions = lOptions; 
    } 

    public List<string> Options 
    { 
     get { return lOptions; } 
    } 

Thứ hai, tôi đã thêm một tài sản Tùy chọn để lớp CustomPropertyDescriptor:

public List<string> Options 
    { 
     get 
     { 
      return m_Property.Options; 
     } 
    } 

Thứ ba, tôi đã phải sửa đổi phương thức GetStandardValues ​​trong lớp kiểu động của tôi (tức làStatesList) để tận dụng các tài sản lựa chọn mới trên Object CustomPropertyDescriptor:

public override StandardValuesCollection 
       GetStandardValues(ITypeDescriptorContext context) 
    { 
     CustomPropertyDescriptor descriptor = (CustomPropertyDescriptor)context.PropertyDescriptor; 
     return new StandardValuesCollection(descriptor.Options); 
    } 

Cuối cùng, tôi đã phải vượt qua trong danh sách các tùy chọn khi tạo một đối tượng CustomProperty mới:

List<string> optionsList = new List<string>(new string[] { "test1", "test2", "test3" });   
    CustomProperty myProperty = new CustomProperty(attr.Name, attr.Value, valueType, false, true, optionsList); 

Thay danh sách tĩnh mà tôi đã chuyển cho ví dụ này, bạn có thể tạo danh sách các tùy chọn cho trình đơn thả xuống của mình theo bất kỳ cách nào bạn muốn, cho phép bạn kiểm soát hoàn toàn các tùy chọn có sẵn.

+0

cảm ơn bạn đã dành thời gian để mở rộng câu trả lời, rất hữu ích. –

+0

ValueType là gì? loại của nó (danh sách )? –

+0

Đây là loại giá trị thuộc tính đang được chuyển, có thể giống như chuỗi, int hoặc một loại tùy chỉnh như Hoa (xem câu trả lời của @ salle55). Bạn có thể sử dụng typeof, như bạn đã chỉ ra hoặc có thể giống như value.GetType(). – Scott

0

trong trường hợp của tôi TypeConverter không áp dụng cho lớp Hoa

[TypeConverter(typeof(StatesList))] // not work 
public class States 
{ 
} 

vì vậy tôi thêm ghi đè trong CustomPropertyDescriptor

public override TypeConverter Converter 
{ 
    get { 
     if (this.PropertyType.Equals(typeof(States))) { 
      return new StatesList(); ; 
     } 
     return base.Converter; 
    } 
} 
Các vấn đề liên quan