I have found this article from http://www.codeproject.com/Articles/687430/Selecting-Forms-Controls-at-Design-Time
This is written in VB.NET, so I converted into C# version.
And I created a class called "DataGridViewBandColumn" inherits from DataGridViewColumn like below.
public class DataGridViewBandColumn : DataGridViewColumn
{
private Collection<DataGridViewTextBoxColumn> _TargetControls = new Collection<DataGridViewTextBoxColumn>();
[EditorAttribute(typeof(BANANA.Windows.Controls.Design.UITypeEditorDropDownCollection), typeof(System.Drawing.Design.UITypeEditor))]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public Collection<DataGridViewTextBoxColumn> ATargetControls
{
get { return _TargetControls; }
set { _TargetControls = value; }
}
}
I can see the property and select other columns from form design time like below.
But as soon as I click OK button on property window, it loses the items that I selected and it is not saved on the Form1.Designers.cs file.
Where do I have to check to fix this?
Anyone has any idea?
Related
I'm trying to show user class property at properties window.
example, this is class code
public class GraphConstruct
{
private List<GC_VisualData> visualDataGroup = new List<GC_VisualData>();
[Browsable(true), Category("Option"), Description("graph option")]
public List<GC_VisualData> VisualDataGroup { get { return visualDataGroup; } set { visualDataGroup = value; } }
}
And UserControl contain this code
public GraphConstruct CONS = new GraphConstruct();
[Browsable(true), Category("graph option"), Description("graph option")]
public GraphConstruct GRAPH_CONSTRUCT { get { return CONS; } set { CONS = value; } }
And properties window showing to me like this.
I want to display my class property at properties window like string, enum, int.
Is it posible? If it possible where I start this work?
Please, give me keyword. I don't know how to search it.
have a nice day
I think you can only show the properties of the UserControl itself, which is shown in the properties window when the item is selected in the designer, not the properties of a property within the UserControl.
https://learn.microsoft.com/en-us/dotnet/api/system.componentmodel.browsableattribute?view=net-5.0
Edit: Dependency properties also show up in the properties window - https://learn.microsoft.com/en-us/dotnet/desktop/wpf/advanced/dependency-properties-overview?view=netframeworkdesktop-4.8#property-functionality-provided-by-a-dependency-property
I Created a custom UserControl using Windows Form Control Library.And I want to create a property of UserControlwhich I can add item to it, then I can select item like comboBox.
WinForms allows you to create a rich design-time environment as well as providing for customised editors at runtime for certain properties that you define.
For example, if I plonk a MessageQueue component onto my WinForms form and view the Properties window, I can see a property named Formatter.
Clicking on the Formatter property however displays a drop-down box showing a preset list of values. This is an example of a UI Type Editor.
One way to do this is to define an enum for your supported values (it could be a dynamic list if you wish).
public enum Muppets
{
Kermit,
MissPiggy,
Fozzie
}
...then after defining your own editor derived from UITypeEditor (see MSDN link below)
class MyMuppetEditor : UITypeEditor { ... }
...you attach it to your control's property that you wish to have a drop-down as so:
[Category("Marquee")]
[Browsable(true)]
[EditorAttribute(typeof(MyMuppetEditor),
typeof(System.Drawing.Design.UITypeEditor))]
public Muppets Muppet {get ; set; }
For more detailed information check out the link below.
More
Walkthrough: Implementing a UI Type Editor
Getting the Most Out of the .NET Framework PropertyGrid Control
EDIT: To allow for dynamic list, try making the property a string because that's what the selection will be bound to and during EditValue() when showing your SelectionControl just display a listbox of your dynamic items
You can do this by using the CategoryAttribute class.
Example:
[Description("Description of property here"), Category("Design")]
public bool my_property;
Check out the MSDN page for a more complete reference on how to use it.
EDIT: In the case of wanting to have a bool property, use this example.
private bool my_bool = true; // this is its default value
[PropertyTab("Property Tab Name")]
[Browsable(true)]
[Description("Description of Property"), Category("Data")]
public bool my_property
{
get { return my_bool; }
set { my_bool = value; }
}
I removed my last answer because I misunderstood your point.
An easy solution would require to make a Collection of enum as a property. The Designer property grid will automatically give you the choice among your initialized Collection with a ComboBox. The displayed names will also be the enum's name.
E.g. (something I made for a TextBox that only allows a certain type of value)
The enum :
enum EnumSupportedType
{
Integer = 1,
Double
}
The class where the property is located :
public class NumericTextBox : TextBoxBase, INumericControl
{
private EnumSupportedType _supportedType = EnumSupportedType.Integer;
public EnumSupportedType SupportedType {
get { return _supportedType; }
set { _supportedType = value; }
}
}
Then these items are suggested in a ComboBox (in the Designer property grid) :
Integer
Double
If you can't use enumerations, you can refer to Providing a Custom UI for Your Properties which seems to be a much harder solution to implement but will solve your problem.
I hope it will help you.
I have a WinForm application with a customized DataGridViewColumn with 1 added property, a simple List<string>. I can change it to whatever sort of collection will make it work, if needed. The problem I am having is that when I set the property in the Designer, it does not persist. When I click OK and then go back into it, it is blank again. I have done extensive research and tried everything I can find but it does this no matter what.
The latest try is below:
[TypeConverterAttribute(typeof(System.ComponentModel.ExpandableObjectConverter))]
public class MyCustomColumn : DataGridViewComboBoxColumn
{
[Editor("System.Windows.Forms.Design.StringCollectionEditor,System.Design",
"System.Drawing.Design.UITypeEditor, System.Drawing")]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
[Description("My custom property")]
public List<string> MyListOfStrings {get;set;}
public MyCustomColumn()
{
this.CellTemplate = new MyCustomCell();
MyListOfStrings = new List<string>();
}
}
I have a custom control with a public collection marked as DesignerSerializationVisibility.Content.
When I add items to the collection using the designer, it adds them to the designer file and assigns all desired values but it gives each element of the collection a generic name, such as MyClass1, MyClass2, etc. I want the "Name" property of each item to become the code name of the item so that I can then access the item by its name in code.
This is the functionality of how a ContextMenuStrip and ToolStrip works. In those cases, the Name property shows up as (Name) in the property grid.
Is there an attribute or something I can use to gain this functionality? Or do I have to write a whole custom designer dialog? If so, what's an example of the simplest way I could go about achieving this?
You can try inheriting from Component to get that feature.
In this example, I created a class called PanelItem, which will be the class used in my collection by my own Panel class. I added DesignTimeVisible(false) so that it doesn't populate the component tray in the designer.
Also, I added a Name property that is hidden from the designer but can be used in code. It seemed to work in my tests:
[DesignTimeVisible(false)]
public class PanelItem : Component {
[DefaultValue(typeof(string), "")]
public string PanelText { get; set; }
private string name = string.Empty;
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public string Name {
get {
if (base.Site != null) {
name = base.Site.Name;
}
return name;
}
set {
name = value;
}
}
}
Then my custom panel control:
public class MyPanel : Panel {
private List<PanelItem> panelItems = new List<PanelItem>();
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public List<PanelItem> PanelItems {
get { return panelItems; }
}
}
Resulted in:
I believe your custom control itself is going to require a DesignerSerializer, and that merely decorating the collection with the the DesignerSerializationVisibility.Content will not be sufficient.
I used ILSpy to check: ToolStrip has its DesignerSerializer set to an internal ToolStripCodeDomSerializer, which I think is responsible for generating all the code properties involved.
I think implementing this will be a bit of specialized work. Here's the MSDN article to get you started: http://msdn.microsoft.com/en-us/library/ms171834.aspx. You're looking for an implementation of the CodeDomSerializer, I believe: http://msdn.microsoft.com/en-us/library/system.componentmodel.design.serialization.codedomserializer.aspx.
The problem is, that the blank row in the DataGrid isn't appearing, ergo user can not add data.
Here is the code:
System.Collections.ObjectModel.ObservableCollection<CoreVocabularyEntry> dataList = new System.Collections.ObjectModel.ObservableCollection<CoreVocabularyEntry>();
public VocabularyToolWindow()
{
InitializeComponent();
dataList.Add(new CoreVocabularyEntry { Foreign = "ja", Native = "ano" });
ListCollectionView view = new ListCollectionView(dataList);
WordsDataGrid.ItemsSource = dataList;
WordsDataGrid.CanUserAddRows = true;
MessageBox.Show(view.CanAddNew.ToString());
}
I can't figure out why view.CanAddNew equals false. This looks like a pretty standart scenario, so there's probably something obvions I'm missing. Can someone tell me what is wrong with the code ? CoreVocabularyEntry is just the following:
public struct CoreVocabularyEntry : IVocabularyEntry
{
#region IVocabularyEntry Members
public string Foreign
{
get;
set;
}
public string Native
{
get;
set;
}
#endregion
}
Thx, J.K.
This may be more simple than above. I had this problem when I did NOT have a default constructor and therefore the datagrid did not know how to add the new row. My only constructor involved a bunch of information to be supplied. Go to the object of that the List<> is made from and add a constructor like:
public MyClass(){}
Hope this helps!
Move WordsDataGrid.CanUserAddRows = true; above the statement where you set the DataGrid's ItemSource.
EDIT:
Just noticed you didn't implement IEditableObject. You'll need to do that for using the editing features of the DataGrid.