I will make an industrial HMI application with OPC. I want to display variables of PLC with radio buttons. But I want to choose the plc varaible on radiobutton properties area. There is a class which includes all PLC's variables. I want to choose different variable for each radiobutton from this class. And if variable is true it will be checked.
To do this I want to make custom radio button on c# and add custom propeties to it.
I can make a custom radio button but I could not relate it's property area with another class varibales. When I clicked property area It should display all variables of a class
How can I do that?
public partial class My_RadioButton : RadioButton
{
private VarsFromPLC _FrPLC;
[Description("Displaying PLC Variables"),
Category("Appearance"),
TypeConverter(typeof(VarsFromPLC)),
Browsable(true)]
public VarsFromPLC FrPLC
{
get { return _FrPLC; }
}
public My_RadioButton()
{
_FrPLC = new VarsFromPLC();
}
protected override void OnPaint(PaintEventArgs pe)
{
base.OnPaint(pe);
}
}
public class VarsFromPLC
{
public bool bTry1 { get; }
public bool bTry2 { get; }
public bool bTry3 { get; }
public bool bTry4 { get; }
public bool bTry5 { get; }
public bool bTry6 { get; }
public bool bTry7 { get; }
public bool bTry8 { get; }
public bool bTry9 { get; }
public bool bTry10 { get; }
}
Before you read the answer about adding such drop-down to property grid, consider these notes:
The usage of a group of RadioButton controls is like the usage of ComboBox to show/modify selected option among available options.
If you want to show value of those properties, it seems you are looking for data-binding.
If just one of those properties can be set to true, you can create a group of RadioButton controls and bind each control to the corresponding property of that class. This way the radio buttons can be used to show/modify those properties.
Note: In this case it seems it's better to have an enum containing all options and just a single property of type of that enum in the class.
If more than properties can have true values, you can use a group of CheckBox controls and bind them to corresponding property of the class.
Anyway if you want to show such drop-down in property grid, you can use either of these options:
You can create an Enum and define your property of that enum type. This way a drop-down will be shown in property grid for your property. (The most simple option)
You can register a custom TypeConverter for your property and overriding GetStandardValuesSupported provide some standard values for the property to show in drop-down. To see an example, take a look at: Type Converters That Provide a List of Standard Values to a Properties Window
You can register a UITypeEditor for the property. As an example take a look at Walkthrough: Implementing a UI Type Editor
Related
I have a class with some properties and methods and I bind an ObservableCollection of objects of this class to a list view in a Windows Universal App.
However a lot of the things I want to display on each item of this list are properties of the class which are derived from other properties: for example I might have a Boolean about the object and then for the UI two colours representing true and false. This Boolean may may also the result of calculations between multiple float properties of the object
My question is can I bind the result of a method in the class to save me from calculating the other properties separately and having properties for those things?
I've looked into converters but they look like they operate on a single property and here I need to be able to act on multiple properties
Assuming you have this
public class MyClass
{
public bool MyBool {get; set;}
public Color MyColor()
{
if (this.MyBool) return Colors.Green;
else return Colors.Red;
}
}
And you want to bind MyColor, you could just make it a readonly property.
public class MyClass
{
public bool MyBool {get; set;}
public Color MyBoolColor { get { return this.MyBool ? Colors.Green : Colors.Red; }
}
You then proceed to bind and use MyBoolColor as you wish. Basically, what you now have as methods beceome the get part of read-only properties.
This is of course a very short proof-of-concept which might need to be adapted to your actual code.
i am trying to use Property Editor for my user control but it doesn't work.
if i set the property in the form load if works, but if i want to use the property editor it don't save my changes (when i click again in the property editor it comes clear)
this is how i define the property in my user control:
private List<Field> _searchField;
public List<Field> SearchField
{
get { return _searchField ?? (_searchField = new List<Field>()); }
}
You need to apply DesignerSerializationVisibility attribute to your property with DesignerSerializationVisibility.Content.
This tells the code generator to produces code for the contents of the object, rather than for the object itself. It helps in code generation for types other than primitive types.
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public List<int> SearchField { get { return _searchField ?? (_searchField = new List<int>()); } }
I have created a custom tab control for my Windows application. The custom tab control extends
System.Windows.Forms.TabControl. The reason why I created a custom tab control is so I can expose a property in the Visual Studio Properties window that allows me to define individual fonts for each tab page in the custom tab control. Here is a quick look at the class definition:
[ToolboxItem(true)]
public partial class CustomTabControl : System.Windows.Forms.TabControl
To store each individual name/font pair I created a nested class inside CustomTabControl:
[TypeConverter(typeof(TabFontConverter))]
public class TabFont
{
public string Name { get; set; }
public Font Font { get; set; }
public TabFont()
{
}
public TabFont(string name, Font font)
{
this.Name = name;
this.Font = font;
}
}
(Note the use of the TypeConverter property above the TabFont class. I added this because somewhere I read online that this was required if I am going to expose this type in the Visual Studio designer.)
Here is the converter class (which is also nested inside CustomTabControl):
public class TabFontConverter : TypeConverter
{
public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] filter)
{
return TypeDescriptor.GetProperties(value, filter);
}
public override bool GetPropertiesSupported(ITypeDescriptorContext context)
{
return true;
}
}
I defined a class variable to store the custom tab fonts as a List:
private List<TabFont> _CustomTabFonts = new List<TabFont>();
To populate this list, I added an event handler for ControlAdded:
this.ControlAdded += new ControlEventHandler(CustomTabControl_ControlAdded);
Here is how I populate the list inside the event handler:
private void CustomTabControl_ControlAdded(object sender, ControlEventArgs e)
{
if (e.Control.GetType() == typeof(TabPage))
{
TabPage newTabPage = (TabPage)e.Control;
Font newTabPageFont = newTabPage.Font;
_CustomTabFonts.Add(new TabFont(newTabPage.Text, newTabPageFont));
e.Control.Font = newTabPageFont;
}
}
And finally to tie it all up I defined the following code allowing the Visual Studio designer to access/modify the custom tab font list:
[DefaultValue(typeof(List<TabFont>))]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public List<TabFont> CustomTabFonts
{
get { return _CustomTabFonts; }
set { _CustomTabFonts = value; }
}
After rebuilding I switch back to the Visual Studio design view, added a CustomTabControl to my main form by dragging one from the Toolbox., then I added 2 tab pages named "Tab 1" and "Tab 2".
This is what the properties box shows for my custom tab fonts property:
Note that it shows the type as a Collection and provides a button [...] to click for editing. When I click the button here is what I see:
I have a couple questions regarding the property editor.
The right side of the property editor shows both the Font and Name
for the selected tab. I only want to be able to change the Font, not
the name. How can I either hide the name field or at least make it
read only? (I would prefer the name field not to show there at all
because I don't want to be able to change it and it's also redundant
because the names are already shown on the left side of the property
editor.)
The left side of the property editor shows the list of tabs which is
exactly what I want. I do not, however, want to allow moving, adding,
or removing any of these members. How can I either hide or disable
the Move (up/down arrows) and Add/Remove buttons?
The left side of the property editor has a heading named "Members".
Can I change that to say whatever I want? Something like "Tab Pages",
etc.
The right side of the property editor has a heading named "Misc". Can
I change that as well?
Thank you very much.
Jan
____UPDATE____
If there is a better/different way of doing what I am trying to do I am open to all suggestions. I am new to this and what I have done so far has been based on various results from different web sites.
I would really like my property to appear in the designer similar to the way margins are shown. Instead of a popup window with a list of tab pages/properties I would like an expandable list with each list item being the tab name followed by the font, which you could then click to edit the font only. Something like the following:
I can't answer the Update question, but I'll have a go at the other two:
Changing the text "Members": The only way I can see of doing this is to create a custom CollectionEditor which opens a custom CollectionEditor.CollectionForm. I haven't tried this though.
Stopping the "Name" property from appearing in the editor: Yes, this can be done in the TypeConverter.GetProperties method by filtering the result. I didn't find the "filter" argument to the TypeDescriptor.GetProperties method any use, but that may be because I wasn't using it correctly. The problem is that, once created, a PropertyDescriptorCollection is read-only, so I copied the contents of the result but missed out the item I didn't want. This should work:
public class TabFontConverter : TypeConverter
{
public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] filter)
{
PropertyDescriptorCollection rawResult = TypeDescriptor.GetProperties(value, filter);
PropertyDescriptor[] arrRawResult = new PropertyDescriptor[rawResult.Count - 1];
int i = 0;
int j = 0;
while (i < rawResult.Count)
{
if (rawResult[i].Name != "Name")
{
arrRawResult[j] = rawResult[i];
j++;
}
i++;
}
PropertyDescriptorCollection filteredResult = new PropertyDescriptorCollection(arrRawResult);
return filteredResult;
}
There are properties that I want to not be editable via the property grid, but I still want them to be visible, even expandable.
How do I do this?
you can use [ReadOnly(true)] attribute on properties which you want to make read only like this
[ReadOnly(true)]
public int ReadOnlyProperty
{
get
{
return _ReadOnlyProperty;
}
set
{
_ReadOnlyProperty = value;
}
}
I'm trying to make an object, configureable/editable with a propertygrid.
This is all going well, except for objects inside objects.
I've got an object/class named "ContactInformation". And inside that object I've got an object named "Correspondence".
This is how that part looks:
[Browsable(false)]
public Correspondence Correspondence
{
get;
set;
}
public int CorrespondenceStatus
{
get { return this.Correspondence.Status; }
set { this.Correspondence.Status = CorrespondenceStatus; }
}
public string CorrespondenceComment
{
get { return this.Correspondence.Comment; }
set { this.Correspondence.Comment = CorrespondenceComment; }
}
public DateTime CorrespondenceDate
{
get { return this.Correspondence.LastSend; }
set { this.Correspondence.LastSend = CorrespondenceDate; }
}
That way I can show the properties/variables of the object inside the object, in the propertygrid.
Anyway, when I edit the values now, and press enter, or click somewhere else, instead of keeping it the value I just typed in, it changes back..
Anyone got an idea why this is happening? Or maybe a better idea to show the properties of objects in objects in the propertygrid?
To edit properties inside an object (this is what you see for example with the winform editor with properties like Font, or Padding, ... where you can "expand" the oject clicking on the 'plus' icon) , you can use the ExpandableObjectConverter class, like this:
[TypeConverter(typeof(ExpandableObjectConverter))]
public class Correspondence
{
...
}
and remove the Browsable(false) of course:
public Correspondence Correspondence
{
get;
set;
}