What to extend for a new custom control? - c#

Some people suggest to just extend Panel but I also know about UserControl that sounds like something I should extend to make my own control.
Panel vs. UserControl vs. Control vs. another_alternative
// inheritance depth:
Control
Panel : ScrollableControl : Control
UserControl : ContainerControl : ScrollableControl : Control
All I need is a rectangle to draw and full WinApi ability (Handle, WndProc etc.). But I want to avoid all the extras that might come into the play. I want to use my custom controls to add them to standard forms. No extreme actions.
On the other hand UserControl extends ContainerControl that might have functionality I want (I'm not sure).
I inherited from Control for an OpenGL box and some other simple controls. They work fine so far. I haven't noticed any functionality-loss. Does something speak against Control ? (in case I don't require any extra functionality)

I think the unofficial and accepted "standard" is to just inherit from UserControl. At least that's what I've seen everywhere else. That does not make it the right thing though!
On the other hand, I think you also may be too concerned about the "right thing" to do here. To me, this is almost similar to premature optimization. You want to make sure that you spend your resources wisely.
Also keep in mind that things like this can always be changed later.
If you're concerned for a reason, I would definitely pick the simplest of the controls with the lowest inheritance depth.

Mostly UserControl is the best class to inherit from. Another option could be to inherit from the class that we want to customize.
In your case, Panel should be the best class to inherit from as it is the simplest control class that would serve your requirements.

Panel would be ideal here because you are not defining a layout for the control. Nor does it need a ControlTemplate. Custom rendering schemes generally come with the recommendation to use Panel. While Control is the simplest 'layout' element you can get at, Panel has the ability to host child controls should you need to later. Perfect!

There is a description of what exactly differentiates UserControl from ContentControl in the "Pro WPF" book, which gives more information than MSDN. Here is a direct link to the section:
http://books.google.ca/books?id=znAVMHNSen0C&pg=PA518&lpg=PA518&dq=%22taking+a+closer+look+at+user+controls%22&source=bl&ots=DjZT-9JCQd&sig=R4MoAzW72PaHvqgZjxPnkkJRs6c&hl=en&sa=X&ei=OdQIUrPgDeTYyAGl6oHYAQ&ved=0CC8Q6AEwAQ#v=onepage&q=%22taking%20a%20closer%20look%20at%20user%20controls%22&f=false
The most interesting difference is how it handles routed events. All events raised by contained elements have their Source reset to the UserControl itself.
I think the conceptual difference is that a ContentControl "contains" its content, while a UserControl's content is "part of" the UserControl. Thus a ContentControl is a distinct element (is focusable / a tab stop) whose contents are handled separately; and setting the content of a UserControl is part of its design process, whose elements are handled directly in the UserControl's code-behind.
So, my rules are:
If the user is meant to inherit it and handle content in code-behind, inherit UserControl.
If it's meant to be used as-is and given arbitrary content, inherit ContentControl.
If it defines its own content, and doesn't have a placeholder for arbitrary content, inherit Control and set its Template.
If you just want a rendering surface, I don't think you would need a Control. You can use an ImageSource for this, like InteropBitmap or D3DImage, which can be attached to an ImageBrush. For example, it could be used in a stand-alone rectangle:
<Rectangle>
<Rectangle.Fill>
<ImageBrush>
<ImageBrush.ImageSource>
<!-- ImageSource here -->
</ImageBrush.ImageSource>
</ImageBrush>
</Rectangle.Fill>
<Rectangle>
Or anywhere else that accepts a Brush, including the Background of another control.

Related

Contentcontrol or dockpanel for navigation wpf

I use a Contentcontrol to show the user controls of the program, Now there is a problem for me to close the user controls After searching, I found an example that The user controls is loaded on a DockPanel
Now my questions:
What is the difference between these two controls? (Dockpanel vs ContentControl)
Is it okay to use this control(dockpanel) Instead of Contentcontrol to display application user controls?
Is there a similar code for Contentcontrol?
ucChild ChildWindow = new ucChild();
ChildWindow.ParentControl = this.UIPanel;
UIPanel.Children.Clear();
UIPanel.Children.Add(ChildWindow);
Standard disclaimer for people coding WPF like it is WinForms: First off; direct UI manipulation like this is a bad idea. You should
be modifying a view model and allowing the binding system to update
the UI. Use the MVVM pattern; WPF will work for you instead of
against you
To your actual questions:
Everything. I mean; they both inherit from FrameworkElement but that's about it in terms of commonality.
A DockPanel is as the name suggests, a Panel. That is; it controls the layout and sizing of one or more child elements. Specifically, DockPanel is good at situations like the following: you want an element to use up a full column of width, then another span the top (except for the previous element) and have the last element fill the remaining space.
A ContentControl is basically a placeholder, its purpose is to expose a settable (and most importantly, bindable) Content property that you can stuff another control into. Even better; you can put an actual object there and use a DataTemplate to control the display (this approach would conform to MVVM).
You can't really replace one with the other, see above
No. ContentControl is not a Panel and so does not have the Children property.

Where does the look of wpf come from?

I just read the book on WPF from Thomas Claudius Huber. He stated, that all WPF controls are "lookless". They just get their look (and visual tree) from their ControlTemplate. That raises one question: Where does the look of WPF come from?
I mean: the Button has a ControlTemplate with some Borders and a ContentPresenter. Where do these two (Border and ContentPresenter) get their look from?
I already googled and found, that Border is a Decorator and sets its look in the OnRender-Method.
Is that the bottom line? Do all other elements which don't have a ControlTemplate define their look in the OnRender-Method?
Short answer: Yes. All visual elements that are not Controls and have a "look", define said look in their UIElement.OnRender method override.
Long answer: Controls don't use the OnRender method to define their looks. Instead, their "looks" are defined in Styles and Templates. When no Style or Template is defined explicitly in an application, WPF Controls simply use their default Styles and Templates from the current system Theme (for more info on Themes, check this MSDN article).
Let's just say that the Framework has its own Resource Dictionaries with default Styles for all built-in controls. For instance, here is the default ControlTemplate of the ComboBox: ComboBox Styles and Templates
That being said, there are several visual components that have their looks defined through code, usually through the OnRender override. They're not Controls; they're Decorators, Shapes and things like that. Things that do have a "look": Border, Rectangle, etc. But in the end, all Controls have look thanks to these elements because all ControlTemplates are made up of either these elements, or other Controls.
TextBlock, as Run, FlowDocument and other similar elements, are special elements created specifically for text renderization. They fall into a similar category than Shapes or Decorators, except they specialize on text rather than graphics. TextBlock, for instance, is not a Control, and defines its look on its OnRender method. Label, on the other hand, IS a Control; but if you check its Template, you'll see it ends up using a TextBlock to show the text.
There are other elements (like ContentPresenter, ItemsPresenter) that have no look whatsoever, not implicit, not by default, not by Styles or Templates. These are logic elements, that define the structure of the view. ContentPresenter, for instance, grabs the Content and ContentTemplate properties of a ContentControl, and makes sure that said Template is correctly rendered and bound to said data, so to speak. But they have no visual representation of their own.
Oh, and I almost forgot about Panels. Panels are not Controls, either, and they do have a look of their own. But similarly to Presenters, they're also logic elements that define how the other visual elements are visualized. More specifically, their layout.

Controls on inherited form are locked, can it be undone?

Setup:
I have created a Form that I wish to have serve as the base from which I will inherit other forms. This base form serves as a "template" of sorts, but it also provides a good deal of functionality related to the structure, as well as the interrelation of all of the controls provided.
A primer for the images that follow... The top info-colored bar is a custom control inherited from ToolStrip. The bottom strip is another custom, again inherited from ToolStrip. The left white block is a TreeView and the right block is a TabControl (having deleted all TabPages from it...I intend for these to be added in the inherited forms).
Image of base form in designer:
Image of inherited form in designer:
Clearly, the only difference is that when I open the inherited form, I get a little box icon superimposed over each control, and when I click them, I get the padlock telling me I cannot edit.
The problems:
All controls on the inherited form are locked. I have researched the issue of visual inheritance, and as far as I can tell, I'm not using any controls that expressly do not support it, as this link suggests there are. In this Q&A, Hans suggests changing the modifier on those controls, which I have done. In fact, I tried both Public and Protected, all to no good result.
I am stumped.
This is a technical restriction in the designer, it is specific to the SplitContainer control you are using. And some other ones. The trouble-maker is the ISupportInitialize interface.
Controls use this interface when they can't afford the properties of the control to be assigned in an arbitrary order. The designer helps when it sees that the control implements this interface, it calls the BeginInit() method when it starts assigning properties, EndInit() when it is done. The control uses these methods to delay the side-effect of property assignments, the EndInit() method makes them effective. Important for SplitContainer, the minimum sizes of the panels also affect the splitter position.
Perhaps you can see the rub, the InitializeComponent() method in the base form class has already called ISupportInitialize.EndInit(). So modifying properties again in the derived form class is unlikely to turn out well. The designer protects the control from this by locking it.
Very inconvenient, there is no simple workaround. If modifying the SplitContainer in the derived form class is a hard requirement then you'll have to give up on inheriting it or write the code by hand in the derived class constructor.

Winforms Creating Dropdown style panel

I am attempting to create my own custom Autocomplete style dropdown control in c# .net2.0. For speed of development I have built my control as a UserControl but have hit on an issue of doing it this way.
When the custom drawn dropdown gets drawn I have to resize the UserControl area to be able to display the list of options.
Ideally I want to be able to mimic the drodpown list behaviour in that the list of options is drawn 'floating' and is not constrained by the UserControls height and width (nor even the parent forms boundaries). A tooltip is another example of the unconstrained 'floating' that I desire.
The only way I can think of achieving this is to create on the fly a new form with no border or title bar and display this when the popup is required.
Is there a better (but also quick) way of doing this?
TIA
You would need to use a Form or NativeWindow to allow the control to float correctly. To make a form follow the control is easy enough but it is more difficult to implement and handle all of the focusing/hiding issues especially if you need seamless tabbing/key navigation.
You can try creating a control that is based off the ToolStrip Drop Down Button control. I believe that this control has the functionality that you are looking for. I found this reference for creating controls based off the ToolStrip, you might try starting with this.
http://blogs.msdn.com/jfoscoding/attachment/1335869.ashx

Subclass built-in WinForms control?

I've come across the feature in Visual studio to auto-generate a subclass of a custom control using Add New Inherited User Control.
But I haven't found a clear description on how to e.g create a subclass of Button for instance. Apart from the actual way to do it, I'm also interested if VS provides helpful code-generation for this?
You just create your own class that inherits the Control, that you would like to subclass. For instance:
class BetterButton : Button { ...}
That is the easy part. Now you have the option to override various methods or properties, depending on what you want to achieve with your new Control. It could be anything, really. One thing I often see used is overriding OnPaint to get the control drawn in a custom way; and still getting the behaviour of the original control.
In terms of UserControls, I often see that a "parent" UserControl contains some UI logic and basic UI elements, while the subclassed controls are refinements of the parent for specific use.

Categories

Resources