I am creating a simple control in C#, and I have come across a problem. I have created 2 properties for my control(it's a button), and the 2 properties are GradientColor1 and GradientColor2. The only problem I am having while creating these, is that I do not know how to set them to have a default property. I know I could do:
GradientColor1 = Color.Black;
GradientColor2 = Color.DarkGray;
Under my constructor, but I want it so they have the ability to click the 'Reset' item in the context menu under the properties panel. As you can see, right now it's disabled:
http://i.stack.imgur.com/ds3AA.png - Can't post images yet.
I verified that attributing your property with the DefaultValueAttribute will enable the Reset menu item. However, you will also need to initialize the value of the property in the constructor.
Related
This is my first question here so bear with me.
I've encountered a bug in my software where multiple radio buttons in a given control are both capable of being selected simultanously as shown here. Note that this is a very large program.
Multiple Radio Buttons Selected in One Control
While debugging this I found the cause of this behavior is that the ReadOnly attribute on the "Checked" property for the RadioButton class is set to true. In additional, it seems as though the ReadOnly attribute for all properties on the RadioButton are set to True. I was able to confirm this was causing the unexpected behavior by changing the value of the ReadOnly attribute via reflection back to false. Interestingly, when this occured every radio button in my application experiences the same problem.
I was able to track down at what point the attributes changes. In a different form I show some objects on a property grid, when I set the SelectedObject of that property grid to the object thats when all of the attributes change. The form with the property grid and the form with the radio button are not common in anyway.
I've been unable to track down the source of this problem for some time now. If anyone has any ideas as to how this is possible it may be able to help me figure out where the issue is in my program.
Here are pictures of my debug window showing the ReadOnly attribute value on a radiobutton just before and just after I set the SelectedObject property for the property grid
Just Before
Just After
Thank you.
Edit 1:
Here is the code that sets the property grid. Line 179. While debugging there are 3 different sub property objects that need to be shown in different tabs. The first causes no issues. The second does.
Property Grid Code
Edit 2:
Solution
Thanks to all the people who commented. I was actually able to figure out the solution to the problem with help from the following thread.
Setting ReadOnly Property in PropertyGrid
Basically, there was a spot in my code where I was setting the ReadOnly status of all attributes in an object to True. It seems as though there is some kind of common "ReadOnly" attribute that is shared among all objects if they do not have a special define.
My original solution was to first check if the ReadOnlyAttribute existed before setting its value like so.
Original Solution
However this was returning True for properties defined like this
Non ReadOnly Property
But False for properties like this
ReadOnly Property
My guess again is that there is some kind of inherit attribute that was getting found.
My solution therefore was to check with the following function.
Final Solution
Putting this check in my SetReadOnly() function solved my problem.
Solution
Thanks to all the people who commented. I was actually able to figure out the solution to the problem with help from the following thread.
Setting ReadOnly Property in PropertyGrid
Basically, there was a spot in my code where I was setting the ReadOnly status of all attributes in an object to True. It seems as though there is some kind of common "ReadOnly" attribute that is shared among all objects if they do not have a special define.
My original solution was to first check if the ReadOnlyAttribute existed before setting its value like so.
Original Solution
However this was returning True for properties defined like this
Non ReadOnly Property
But False for properties like this
ReadOnly Property
My guess again is that there is some kind of inherit attribute that was getting found.
My solution therefore was to check with the following function.
Final Solution
Putting this check in my SetReadOnly() function solved my problem.
i used PropertyGrid control to display properties on gridview.
i have taken an reference of this link http://www.c-sharpcorner.com/article/using-property-grid-in-c-sharp/
which is showing like this
But i need checkbox just before the property name shown in red mark on check/uncheck for any property i need to build expression.
I recommend reading this: How do I change boolean properties with one click in PropertyGrid.
It extends the PropertyGrid control and defines its checkbox controls using UITypeEditor.
As Reza mentioned, your choice of control does not appear optimal. You should probably create a form with TextBox, CheckBox, ComboBox etc. Or make use of DataGridView if your display is catering for multiple records at same time.
If you most definitely want to customize PropertyGrid, here is my another answer which might help you start with.
Linked answer:
You can make use of TrackBar. Note that PropertyGrid by default does
not allow you to add controls like these to it. So, you will need to
do some work here. You will need to create a class that inherits from
System.Drawing.Design.UITypeEditor. Next you will have to set the
editor attribute for the property that has to display track bar as
control. Note that unless you do custom paint, it will be shown as
modal dialog or as dropdown editor.
I am working on a project in which I am using a property grid to display the properties of the selected control.
The Property Grid is fixed to the left edge of the container and in the rest of the space I have the form I am designing.
On clicking a control on the form, the specific control’s property is getting selected.
In the above figure, I have selected the textbox and the textbox’s properties get shown on the propertygrid.
Here if you observe, by default, the Name property is highlighted as well.
Is there some way to unselect this property programmatically?
I have tried some suggestions online but none have helped. I am not able to find find a way to remove all selections from the PropertyGrid, but its behaviour seem to be different form a DataGrid...
Here is why I need this...
On selecting a control, if a property in the property grid is selected, then the property is getting modified.
For example, If i cut the control using Ctrl + X, the selected value in property grid is getting cut which in some cases is forcing user to set the property before modifying anything on the form.
I have tried selecting multiple controls, but in that case alse the selected property seems to be persistent
Since PropertyGrid uses DefaultProperty to select a property in its grid, as an option you can set DefaultProperty attribute at run-time for your object to a non-browsable property, for example:
this.propertyGrid1.SelectedObject = null;
TypeDescriptor.AddAttributes(someControl,
new Attribute[] { new DefaultPropertyAttribute("Site") });
this.propertyGrid1.SelectedObject = someControl;
Well, what you are trying are hacks. It is never a good idea to do such hacks particularly if you are not the only person that use the software.
In your case, the focus should be on the designer while you interact with it. So if the user press Ctrl+X, the designer should respond to the keyboard and it should not have any effect on the property grid (as only one control can have the focus at the same time).
Thus it is up to you to make sure that your designer is focusable, that it has the focus when initially displayed, that it get the focus when you press the TAB key. Pressing the TAB key again should put the focus on the property grid so that user can interact with the grid without using the keyboard.
If you have more than these 2 controls, then obviously TAB should also stop at any appropriate controls. Also, it can be a good idea to have some direct shortcuts like F4 to (show and) activate the properties pane.
If you are not able to make it works, then the best compromise would be to use another windows for the properties grid. By using a distinct Tool windows for the properties, it should not respond to the keyboard when the main windows has the focus.
Here are some links that might help you:
Panel not getting focus
Control.Focus Method() — See Remarks section.
In any case, you should not prevent Ctrl+X to works as expected when the property grid has the focus and a property is selected. Users don't like software that do not follows UI conventions.
As a software developer, you should as much as possible ensure that your application follows standard behaviors. I recommend you that you take one or 2 extra days developing your software properly instead of doing hacks.
Often, compromise to gain a few days will never be fix and will be a pain for many years. Better to do it right from the start. Unselecting an item in the property grid is not an acceptable workaround. Your manager should not allows you to do that.
I know when I use Enum and put it as Property for class/UserControl, it will show/display it with drop down list like this:
But is this the only way to display available values like "drop down list"? Do we have other ways to do it?
Edit: The scope is Windows Form Application
For who didn't understand me
In that image(http://i.stack.imgur.com/NMank.png) where wrote "DataBase" is the Name of the Property in design time.
The values: NotChoseYET, ChooseDataBase, ThereAlreadyDataBase are values in Enum I created.
As you can see they displayed in a DropDownList in the design, so I want to ask if there are other ways to display like that without Enum?
Update
After tons of searches, I found what I had answered was only partially correct, so I would like to answer it again.
The answer to your question is a definite NO, we have some other way to show values on property as DropDownList. Like what I mentioned in my old answer, if values come from some kind of Set, or in other word it belongs to a collection of values, it will be displayed as a DropDownList without any extra efforts (because the UITypeEditor has been specified for them, you will understand this point later). Here are 3 examples:
If a Property is a bool, in the designer it will show you a DropDownList contains True and False;
If a Property is a Font.Name, in the designer it will show you a DropDownList with SmallIcon;
if a Property is a Color, in the designer it will show you some DropDownList encapsulated in a TabControl.
From those "native" examples, you may realize a fact: we could somehow use some controls other than a simple DropDownList in the Property Tab during the design time. For example, a Color property gives a TabControl instead of a simple DropDownList, and a Font.Name property gives a customized DropDownList.
Yes, this is the second thing I am going to talk about. You are not only able to customize the items in the DropDownList, but also the View of that Value Choosing Editor.
However, this is very tricky and non-trivial. You are not recommended to do this unless it really adds value to your user control in the design time.
In short, you need to inherit from UITypeEditor, and override 2 functions:
GetEditStyle(), which
indicates to the design environment which kind of user interface your UI type editor implements
and EditValue(), which
establishes the interaction between the design environment and the user interface for editing your custom type
Then for your property which makes use of the Editor, you need to add EditorAttribute to it to specify the Editor used when selecting value of that property.
For better details, you are suggested to check this MSDN walk-through, which explains how to design a customized Value Editor in the design time.
Now back to the point where we left over. The native type, like bool and Color, has already bond to
a UITypeEditor, thus no further working should be done.
Old Answer:
For properties, you need to choose a value from a kind of Set, and all elements in that Set will be displayed as Items in a DropDownList during design time. When you try to define the Set, Enum is one method to define them. Also, you can use set of struct, like Color. In other words, if you have a Property that returns Color (or other structs), during design time it will appear as a drop down list.
You can easily add items to a combobox control by using its .Items property:
private void TestForm_Load(object sender, EventArgs e)
{
for (int i = 0; i < 10; i++)
{
// add items to the combobox
// you can use any object. The .ToString() method will be used for displaying it
cbxTest.Items.Add("This is test string " + i);
}
}
This will yield the following form:
I came across this question as I recently needed to do the same.
I posted a question ... which in the end I anwsered myself here.
In a nutshell: Implement a type converter
GetStandardValuesSupported(ITypeDescriptorContext context) to return
true and GetStandardValues(ITypeDescriptorContext context) to return
the StandardValuesCollection for the property type. Finally just
decorate the property like so:
[TypeConverter(typeof(MyClassConverter))]
public MyClass MyProperty { get; set; }
The designer property window will now have a dropdown with valid values.
I am working on a winforms app with a DataGridView control on it, and I am experiencing some frustrating things.
First off, I want to turn off AutoColumnGeneration, but it's not listed in the properties. No problem, I can do that with a line of code...and this is where it gets weird:
In my code, the DataGridView is inaccessible. Its like it doesnt exist on the form. Looking into this, its because the designer is declaring it as part of the InitializeComponent() method instead of where it initializes all the other controls.
Because its in the designer, any change I make there gets reversed so I can't fix this.
Is there any way to stop visual studio from doing this? I found a hack around it by using one of the datagrid columns (which ARE accessible) to create a reference to the datagridview its associated with and access it that way. It works, but its ugly and not intuitive at all.
I think I found it:
In the designer, click on the DataGridView control, and change the property of GenerateMember to true. I'm guessing it is set to false.
That property is used to do just that: hide the control from the code windows. It's useful for Labels or ToolStripSeparators that you don't need to deal with in code.
I personally use the binding source as the datasource which can even be an object and then under columns it will list all of the available columns and you can pick and choose which ones are visible as well as a slew of other options including formatting.
Click the drop down on the datasource and Add a new data source and select the necessary object, in my case an order detail object. Here is some of my designer code which is created by VS2010
this.dgvOrderDetails.DataSource = this.orderDetailBindingSource;
this.orderDetailBindingSource.DataSource = typeof(OrderDetail);
And the binding source code that sets up the data to fill the datagridview (I coded this part)
orderDetailBindingSource.DataSource = orderDetList;
Then just click the ellipses on the Columns property of the datagridview and it will have all the columns listed that are available from the object and I set the ones I want visible, the order, format etc.
As for the 2nd issue I don't think you'll have that problem once you use the designer to make the changes I listed above.
In my case, I declared a private property in the Form's partial class (the file for my code, not the Designer's file) to return the control by navigating through the Controls hierarchy.
private DataGridView MyGrid
{
get { return (DataGridView)this.Controls[0].Controls[1].Controls[0].Controls[1].Controls[0]; }
}
I agree, there ought to be a better way, such as Visual Studio Designer declaring the control like it does most other controls on the form. In the meantime, this works.
Warning!
If the form's control hierarchy is ever changed, the property's definition will have to be manually updated.
Edit
I have a better solution - at least in Visual Studio 2012.
While in the form Designer, with the DataGridView selected, open its properties and look for the GenerateMember property (under the Design node) and ensure it is set to True. Once set to True, the Designer will declare a member variable for the DataGridView control.
The strange thing is that the default value appears to be True, so I'm curious how it was changed to False? Perhaps I mis-clicked when setting the name?
By the way #LarsTech's answer is the same as this update.