Usage of generics with windows forms - c#

I wish to create custom control with Items property.
Is it safe to return class ItemColection that implements IList<Item>, because i didn't saw this in any prebuilt controls?
What's the best way to implement this?

Yes, you can use pretty much anything. A Form is (just) a class.
That you don't see examples is mostly due to the fact that WinForms is a .NET 1.0 technology. Very few additions or changes since then.
And unless you need specific functionality, just keep it simple:
public IList<ItemType> ItemsCollection { get ... set ... }

There is no problem to create a property of type inherited from ILIst for a control. But if you are building a control it's better to make your property editable with PropertyGrid in design time. To make it editable you should create your own collection of items inherited from CollectionBase and create a property of that type.
Check out this article: Creating a Custom Collection for Use in a PropertyGrid
And after that don't forget to make your Items property editable in design time by setting appropriate attributes:
[Browsable(true), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public YourItemsCollection Items
{
get { ... }
set { ... }
}

Related

Change the backcolor of some properties of propertygrid control [duplicate]

I have a .NET PropertyGrid control which displays properties of some class. I want to change the color or font or background color(it doesn't matter just that they look different from the other displayed properties) of some property. I can do with writing custom editor but I was wondering:
If an easier method exists?
If I use custom editor then how do i change the editor of built-in types like bool, int etc?
No can do. The class that determines how an item is drawn is PropertyGridView. The source code is interesting, it almost made it:
private /*protected virtual*/ PropertyGridView CreateGridView(IServiceProvider sp) {
return new PropertyGridView(sp, this);
}
Nope, looks like at the last minute they decided against making the method overridable. The PropertyGridView class was also marked internal. Replacing all this code (there is a lot of it) is not a realistic option.
Creating your own UITypeEditor for built-in types is only possible by applying the [Editor] attribute to the properties in the class you want to edit. That's not a general solution. Consider creating your own form to make the object editable instead.

Can we change the text/background color of an individual property in PropertyGrid

I have a .NET PropertyGrid control which displays properties of some class. I want to change the color or font or background color(it doesn't matter just that they look different from the other displayed properties) of some property. I can do with writing custom editor but I was wondering:
If an easier method exists?
If I use custom editor then how do i change the editor of built-in types like bool, int etc?
No can do. The class that determines how an item is drawn is PropertyGridView. The source code is interesting, it almost made it:
private /*protected virtual*/ PropertyGridView CreateGridView(IServiceProvider sp) {
return new PropertyGridView(sp, this);
}
Nope, looks like at the last minute they decided against making the method overridable. The PropertyGridView class was also marked internal. Replacing all this code (there is a lot of it) is not a realistic option.
Creating your own UITypeEditor for built-in types is only possible by applying the [Editor] attribute to the properties in the class you want to edit. That's not a general solution. Consider creating your own form to make the object editable instead.

Best way to manage ListViewItems in a Detailed ListView?

I've adopted the following pattern for putting ListViewItems in a ListView with multiple columns (when I want to display information about a list of MyObject types), and I'm just curious to see if this is the best way to accomplish this task, or if there's anything more efficient and readable in code:
Create an inherited ListViewItem class that takes a MyObject object in the constructor - I'll call this MyObjectListViewItem - and a Refresh() method that clears and re-populates the ListViewItem subitems.
Populate the ListView with my new MyObjectListViewItem items.
example:
public MyObject MyObject { get; set; }
public MyObjectListViewItem(MyObject myObj)
{
MyObject = myObj;
this.Refresh();
}
public void Refresh()
{
this.SubItems.Clear();
this.Text = myObj.FirstColumnProperty;
this.SubItems.Add(myObj.SecondColumnProperty); // etc...
}
Suggestions? Better ways?
Have you considered using a BindingSource, or creating your own which implements IBindingListView? This keeps concerns about the data and its state scoped to the data itself and not on any controls which consume it. Since .NET controls are already built to work with BindingSources, you can take advantage of some more robust functionality. Instead of explicitly invoking a screen refresh, the control is simply responsible for responding to events raised by the binding source, and a controller that notifies whether the control is ready to be refreshed without forcing it.
Making ListViewItems that know how to build themselves is a good idea.
If you extend that idea a little, you make the columns know how to build each subitem, which also allows them to be able to automatically sort the ListView, support grouping and copy/drag and drop rows. This is just a few of the things that ObjectListView does for you.
ObjectListView is an open source wrapper around a .NET WinForms ListView control that makes the ListView much easier to use -- as well as adding some very nice new features and getting around some annoying bugs/limitations.
If you did like #Rex's idea of using a BindingSource, the ObjectListView project also provides a data-aware DataListView which is data bindable.

How to implement a Properties window style control/system in Windows Forms?

So what I am trying to do is to have a set UI with certain controls, and I want to have some class instance to fill in the values.
For instance:
Classes that can populate the UI:
Sharpen, Blur, Smear, ... : FilterBase
So whenever the user creates an instances of the above classes, I want to automatically fetch the values based on the UI controls, by using the class instance.
The UI has items like:
.Name (TextBox)
.Amount (NumericUpDown)
.Decay (NumericUpDown)
So if the current instance is s = new Sharpen(), I want to get s.Name to fill out UI.Name.
How do I do this in the best possible way? Elegancy, clarity, performance wise, etc.
I am gonna use reflection, but how do I store the instance of the object (Sharpen, ...) and be type safe? Should I use an System.Object instead? Or T?
public partial class ParamsUI
{
T CurrentFilter (?)
...
}
Also if I use T, how will I know what to cast it to?
Is there a better way?
Since this is using Windows Forms, the most flexible option would probably be to just use the Windows Forms PropertyGrid directly.
You can do a lot of work to customize the look and feel of this. See Getting the Most Out of the .NET Framework PropertyGrid Control for details.
Edit:
If you want to have a very flexible, easy option, and WPF is an option (hosted within an ElementHost), you could consider using WPF.
With this, you could host a UserControl containing nothing but a resource dictionary and a ContentControl.
You could then make a custom XAML file for each item you want to edit, and setup a data template in the resources specifying the mapping of which user control (xaml) to use for each element you want to edit. You can then just set the element to the user control's "DataContext" in code, and it will automatically wire everything up and "just work".

Design problems with .Net UserControl

I have created a UserControl that has a ListView in it. The ListView is publicly accessible though a property. When I put the UserControl in a form and try to design the ListView though the property, the ListView stays that way until I compile again and it reverts back to the default state.
How do I get my design changes to stick for the ListView?
You need to decorate the ListView property with the DesignerSerializationVisibility attribute, like so:
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public ListView MyListView { get { return this.listView1; } }
This tells the designer's code generator to output code for it.
Fredrik is right, basically, when you need to enable the designer to persist the property to page so it can be instantiated at run time. There is only one way to do this, and that is to write its values to the ASPX page, which is then picked up by the runtime.
Otherwise, the control will simply revert to its default state each and every time.
Always keep in the back of your mind that the Page (and its contents) and the code are completely seperate in ASP.NET, they are hooked up at run time. This means that you dont get the nice code-behind designer support like you do in a WinForms app (where the form is an instance of an object).
Just so I'm clear, you've done something like this, right?
public ListView MyListView { get { return this.listView1; } }
So then you are accessing (at design time) the MyListView property on your UserControl?
I think if you want proper design-time support you're better off changing the "Modifier" property on the ListView itself (back on the original UserControl) to Public - that way you can modify the ListView directly on instances of the UserControl. I've had success doing that anyway.

Categories