I have 2 projects:
Project A which consists of a Usercontrol named BaseUC which consists of a RadPanel and a RadGridView (both have modifier set to public)
Project B which consists of a Usercontrol which inherits from BaseUC
(from the class itself). Project A is included as referenced dll in Project B
Now the situation is so:
Both elements from BaseUC are shown in the DerivedUC.
The RadLabel I can edit without problems (properties) in project B
The GridView has its properties grayed out in project B
If I give GridView events which I implement as virtual in project A and overwrite them in project B I run into the problem that I get an exception as soon as I try to fire the events. Same if I try to manually add events to the gridview in project B.
So my question is twofold there but comes down to the basic question if event handling is possible for visually inheritted RadGridViews:
How can I get the RadGridView to have its properties editable in design view in project B?
How can I handle events there?
That is if these two things are possible at all.
You can expose the child controls contained in your UserControl as a public property, that is creating a public property that returns the child control and not just making the child variable public. This will make the child control available to sink event handlers and set public properties. Note that this breaks one of object orientation rules namely, encapsulation....but rules are meant to be broken for certain cases that fits the requirement :)
Related
I have a UserControl with a custom property:
public Size TestSize { get; set; }
I would like this property to show up in the properties window during design time of the UserControl, and not only where the UserControl is used as an instance (e.g. when dragged/dropped on a form).
Example:
In the designer of the UserControl one can set properties like "AllowDrop", "AutoScroll", "BackColor" etc. I would like my custom property to show up just the same way in the designer.
I have considered and tried adding attributes to the property like:
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
but that does not seem to be the way to go.
Any help is appreciated!
If you really want to show the property in the designer of UserControl1, then the property should belong to its base class. That's because of how designer works
Assuming the root element of the designer is UserControl1, then the properties that you see in properties window, are browsable properties of UserControl1's base class (which is probably a UserControl). To learn more about it, read the second section of the answer.
In most cases you don't need to show those properties in designer, unless you want to derive multiple controls from that base and configure that property in design-time of the derived control, but I assume you know your requirement and now you are able to make a decision base on your requiremets.
This is the way that designer works:
It deserialize the .cs file (and looks for InitializeComponent method, or designer.cs file, also considers the designer-related attributes).
It creates an instance of the base class and add it to the design surface, and applies the deserialized property values. (So the instance that you see in designer, is an instance of the base class. It's a trick. For example, that's why if you have an abstract base class, you cannot have the derived class as root designer without some workarounds.)
It creates the whole control/component trees based on the deserialized code. (So the controls which are on design surface are real instances of the controls)
Of course there are a lot of other things happening, like making the extender providers working, or pre-filtering or post-filtering properties in design-time, but in general it works like what I explained above.
More information / Related Posts
Some other related answers:
A similar question/answer for Form: Custom browsable property for Form at design time
An answer explaining how designer works, also contains an interesting example shows how .cs file which is full of syntax errors can be shown in designer: How does Windows Forms Designer work?
I am looking to create an application that will query for address information (first, last, address, city, state, zip). A custom Address Windows control you can use in any application. This control needs to validate zip code and that all fields are properly filled in. I am looking for some tutorials that can help or any guidance On how to create this type of control.
You should consider creating an Address model class that defines the data you are collecting. Individual properties of the class can be bound to the values of controls in your usercontrol gui.
This class can implement the INotifyPropertyChanged and IDataErrorInfo interfaces to help it interact with the windows forms data binding components.
Like #Francesco suggests create a user control. It is essentially a compound or composite control. For address you can add the required text and label controls and maybe the logic to validate them. Then you can reuse this across projects.
Add a class into your windows forms project like this:
public class AddressForm : UserControl
{
//excluding this causes probs with VS designer sometimes.
public AddressForm() : base()
{
}
}
Build your project and you will notice the file icon in visual studio changes, when you double click it you can then design the control by adding simple controls on it.
Make sure you build after any change, and you should also see the toolbox updated when you're designing a form. AddressForm will show up there and you can drag and add it on the form. It is now officially reusable.
See msdn on UserControls for more. Try and run their customer form sample (on the same page) and you should have a good idea.
I've build a base user control, BaseViewControl, it has a dataGridView and a bindingSource on it. Both have protected access modifiers. The dataViewGrids dataSource points to the base forms bindingSource.
Then I created an InheritedUserControl, ApplicationUserView, when prompted I pointed it to my UI assembly. It inherited some other arb UserControl in the same assembly so I manually changed it to inherit my BaseViewControl.
On the ApplicationUserView's bindingSource, I set the dataSource property to my ApplicationUser domain object. The dataGridView then proceeded to populate its columns with the properties in my ApplicationUser domain class in the DesignView, as expected.
Now, in an async callback from my controller object, where the view receives an IList<ApplicationUser>, i set my bindingSource.DataSource = applicationUserList.
I've confirmed that the callback gets called and that the applicationUserList has items in it, but at run time, the grid doesn't show any rows. I suspect it has something to do with the visual inheritance aspect of it all.
I've seen VS create copies of items from inherited forms onto the inheriting form as soon as you try and modify a property of an inherited item before, which has a similar effect, but this is not the case.
Any ideas what I'm doing wrong?
Thanks, HS
I tried to create a custom user control in C# that handles other controls that are added to it. The custom control consists of two panels. What I'm trying to achieve is, that if another control is dragged to my user control in design mode (or added programmatically at runtime) I want that control to be placed on one of the panels.
I tried to handle the OnControlAdded event but that didn't do the trick...
Markus wrote : "if another control is dragged to my user control in design mode (or added programmatically at runtime) I want that control to be placed on one of the panels."
I am going to interpret the above as meaning you want the Design-Time dragged control to become a child control of one of the two internal Panels of your UserControl : if that intrepretation is wrong : please disregard what follows :)
Also, just to avoid confusion : you are absolutely correct when you observe that Panels, or other "container" Controls, in an instance of a UserControl placed on a Form at Design-Time, do not "consume" or "swallow" dragged over controls as you might expect : in fact you can't even select them individually : they are added to the UserControl's ControlCollection.
Fortunately for you, in the design-time drag-drop case there is a good solid code example you can study and use on CodeProject by Henry Minute : Designing Nested Controls : that article will show you how to inherit from ParentControlDesigner so that child controls which are containers of a UserControl at design-time can function as containers in the way you are looking for.
In the case of your wanting the consumer of your control at run-time (programmer) ... assuming they don't have source, so they interact with your UserControl as a "black box," able to "see" only Properties, and Methods, available Events, etc., you've made Public ... to control where an added Control is placed : you have a decision to make about how you wish the consumer to access the Panels. You could expose them "directly" as objects, via Public Properties of the UserControl, or you could expose only a Public method for adding controls for each panel.
Why not just drag it into the panel, or give one of the panels a public accessor and do all your programmatic adding to that panel directly?
I'm trying to create a kind of master/detail UI using an MVP pattern. I have the usual suspects:
interface IMainView{}
class MainView: Form, IMainView{}
interface IMainPresenter{}
class MainPresenter{}
// Numerous domain objects
I also have a UserControl which is also a View of its own MVP triad:
interface ISubView{}
class SubView: UserControl, ISubView{}
interface ISubPresenter{}
class SubPresenter{}
The MainPresenter creates and instance of the SubPresenter, which in turn, creates an instance of SubView. My problem is the Views don't contain references to each other or even know each other exist. They only know about their own presenters but I want to attach one view that is a UserControl to another view that is a Form. Is this possible to do and still maintain each view's ignorance of each other?
Up until this point all the views have exposed the properties needed by each presenter as system types so the presenters would not be affected if a ListBox changed to a ComboBox or a RadioGroup. I'd like to keep it this way if possible but I'm willing to break this pattern if I have no other choice.
My reasons for doing this is the MainView presents the user with a collection of objects. Each object can be one of several (more than 50) different classes. All will implement a common interface but the UI for manipulating each object will vary with the underlying class.
By the way, this is a Winforms application targeting .NET 2.0 (it's compiled as C# 3.0 though)
I solved this by having the subpresenter pass a reference to its view to the main presenter which then passes it to its view, which then assigns it to an empty panel.
subView
|
V
subPresenter
|
V
mainPresenter
|
V
mainView
It's passed as a plain old object so neither of the presenters need to include references to the winforms namespace. The mainView simply assumes its a decedent of UserControl and casts it as such.