how to show user class property at properties window in WPF - c#

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

Related

Custom UserControl - Design-Time support for control repainting

I have created my custom UserControl with some custom properties for it. For example:
[Description("Example Description"),Category("CustomSettings"),DefaultValue("Transmedicom")]
public string DatabaseAddress
{
get; set;
}
Everything works fine. I can change custom property in code and in design-time.
What I'm looking for (and cannot find anything) now is: How could I repaint (reacreate) my UserControl in design-time when my custom property change in design-time.
Let's say when DatabaseName will be changed to localhost UserControl will add and display some Label on my UserControl. It's important to work in Design-Time.
Nothing special there. You just have to set the text to Label inside the property setter. That should update the UI.
private string databaseAddress;
[Description("Example Description"), Category("CustomSettings"), DefaultValue("Transmedicom")]
public string DatabaseAddress
{
get { return databaseAddress; }
set
{
databaseAddress = value;
yourLabel.Text = value;//Set value to Label or whatever
}
}
Try this
private string _databaseAddress = "localHost";
[Description("Example Description"), Category("CustomSettings"), DefaultValue("Transmedicom")]
public string DatabaseAddress
{
get
{
return _databaseAddress;
}
set
{
if(!string.IsNullOrEmpty(value))
{
_databaseAddress = value;
lblAddress.Text = value;
lblAddress.Invalidate();
}
}
}
Both previous answers are correct.
I just want to add that the user control can even react on resizing during design time, using the Layout event.

Create a custom UserControl using c#

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 cannot save property of a control in c#

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?

Auto-generate the code-behind name of designer collection items

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.

How to access properties of a usercontrol in C#

I've made a C# usercontrol with one textbox and one richtextbox.
How can I access the properties of the richtextbox from outside the usercontrol.
For example.. if i put it in a form, how can i use the Text propertie of the richtextbox???
thanks
Cleanest way is to expose the desired properties as properties of your usercontrol, e.g:
class MyUserControl
{
// expose the Text of the richtext control (read-only)
public string TextOfRichTextBox
{
get { return richTextBox.Text; }
}
// expose the Checked Property of a checkbox (read/write)
public bool CheckBoxProperty
{
get { return checkBox.Checked; }
set { checkBox.Checked = value; }
}
//...
}
In this way you can control which properties you want to expose and whether they should be read/write or read-only. (of course you should use better names for the properties, depending on their meaning).
Another advantage of this approach is that it hides the internal implementation of your user control. Should you ever want to exchange your richtext control with a different one, you won't break the callers/users of your control.
Change the access modifier ("Modifiers") of the RichTextBox in the property grid to Public.
Add a property to the usercontrol like this
public string TextBoxText
{
get
{
return textBox1.Text;
}
set
{
textBox1.Text = value;
}
}
I recently had some issues doing this with a custom class:
A user control had a public property which was of a custom class type. The designer by default tries to assign some value to it, so in the designer code, the line userControlThing.CustomClassProperty = null was being automatically added.
The intent was to be able to provide the user control with a custom class at any point while running the program (to change values visible to the user). Because the set {} portion did not check for null values, various errors were cropping up.
The solution was to change the property to a private one, and use two public methods to set and get the value. The designer will try to auto-assign properties, but leaves methods alone.
You need to make a public property for the richtextbox, or expose some other property that does the job of setting the richtextbox text like:
private RichTextBox rtb;
public string RichTextBoxText
{
get
{
return rtb.Text;
}
set
{
rtb.Text = value;
}
}

Categories