Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
See more: C# custom-controls WinForm , +
Hello CP,
 
I'm currently in the process of writing a custom control which inherits from the abstract ListControl (the parent of ListBox). Now I'd like to display scrollbars only I don't know how to do it without inheriting from ScrollableControl.
 
So, how do I add scrollbars without using ScrollableControl?
Posted 4-Mar-13 9:42am
Groulien2.9K
Comments
Sergey Alexandrovich Kryukov at 4-Mar-13 14:44pm
   
Why without inheriting it? What's the idea? We won't be able to help you without knowing the detail on required functionality.
—SA
nbgangsta at 4-Mar-13 14:50pm
   
The control has to be exchangeable with the 'ordinary' ListBox (doing this through the parent class) so that users can get used to the new interface but, in case they're confused, can still switch back. All I really need is the SelectedIndex property which they would both share (and I don't like additional type checking for it).
Sergey Alexandrovich Kryukov at 4-Mar-13 14:53pm
   
Still not clear, as I don't see how it's different from ListBox. All you say tells me that you actually can use ScrollableControl as the base, why not?
—SA
nbgangsta at 4-Mar-13 15:00pm
   
Current situation has a ListBox of which I use the SelectedIndex (defined by ListControl).
New situation allows the ListBox to be replaced (at runtime) by the new custom control of which I also want to use the SelectedIndex property.
(This new control does behave like a list)
By using the abstract class ListControl, I can switch the two more easily (at runtime).
If I use the ScrollableConrol then I can't refer to the same variable without having to check for its type.
Sergey Alexandrovich Kryukov at 4-Mar-13 15:06pm
   
In other words, you need to have list-box view and non-list-box view of the same controls (would be good to know what it is, at least, give it a name). The problem is more general. First, does list-view needs to be exact type of System.Windows.Forms.ListBox? or it can be further derived? Can you explain some ultimate goals of it? I feel that I know the solution, but you approach to it from wrong side...
—SA
nbgangsta at 4-Mar-13 15:09pm
   
I access data by using the SelectedIndex of either the ListBox or the new control but I don't want to have to check types all the time (Don't want to have to check which is being used).
Sergey Alexandrovich Kryukov at 4-Mar-13 15:16pm
   
You did not answer my question. Live out the new view. And it's clear what you may want to do with selection. Do you mean that with the listbox view, you want to use the exact type I mentioned above. Or do you need to make an abstract customizable control which only implements some list-like interface. If some items are also controls, what do you want to show in the list items of the list box?
—SA
nbgangsta at 4-Mar-13 15:42pm
   
The real problem I'm facing is that a lot of events used to perform operations contain code like this:
previewProgressReport(openRepairJobs[(sender as ListBox).SelectedIndex]);
 
The new control can do more than the existing ListBoxes (internal reordering and more), that's the reason it's been requested.
I first tried to inherit from ListBox but that became an absolute mess because the items have child controls and the ListBox doesn't like irregular item heights.
Then I thought it might be better to go up the hierarchy (to ListControl) so that the ListBox logic wouldn't bother me.
We replaced all the (sender as ListBox) code with (sender as ListControl) to see if it harmed the existing code and it didn't.
The new control is derived from ListControl and is working quite well but the scrollbar is missing.
Sergey Alexandrovich Kryukov at 4-Mar-13 15:48pm
   
You are not answering my question. Focus on two modes you mentioned. When you describe the behavior above, you don't explain is it list-box mode or a new one...
—SA
Espen Harlinn at 12-Mar-13 17:45pm
   
I thought you meant something like that control ...
Sergey Alexandrovich Kryukov at 12-Mar-13 18:08pm
   
I'm already mixing up, what exactly "that"; our discussion is a bit vague...
I say that, among other things, ScrollableControl, as a direct, or other indirect base class, will do it's job perfectly well for implementation of such complicated control. There is no need to add scrolls bars manually and synchronize them with children positions. I recently worked at the control based on ScrollableControls, so any custom items behave very well in it...
—SA
Espen Harlinn at 12-Mar-13 18:28pm
   
Understandable, my reply here was supposed to end up somewhere below, not here ...
Sergey Alexandrovich Kryukov at 12-Mar-13 18:36pm
   
:-)
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

You live too many unknown detail of functionality. I'll try to go in a most general way.
 
You probably need to have two modes of the same control. One is something like ListBox, but probably is extended, so you may want to use the System.Windows.Forms.ListBox functionality, or create some other control. As on option, you can create just the "list-box-like" interface, implement it, and allow your user to create alternative implementation. The second mode should show some new behavior.
 
Your problem is not inheriting from ScrollableControl, but inheriting in general.
 
Here is how you can work around it. You need to create a user control with two child controls: each one representing a separate mode. First, you need to start with defining it's common interface. Each of the two child controls should implement its interface (you already named one member of it — SelectedIndex). And then you may need to extend this interface to two specific interfaces. It's more about the list-box-like control. If you want you parent control class to be overridden by the user, you may add a method IListBox GetListBox(). Then the user would be able to change the functionality of list mode by overriding this method and supplying an alternative child control for this mode. You may or may not need this part of functionality; I fail to understand it from your comment. So, you can have this functionality for one or another mode, all modes, or none, it's up to you, but now you know the idea.
 
Only one of these two controls should be visible at a time. Mode switch (you should define a enumeration type with two members representing modes, and the read/write property of this type, to switch) should be done by hiding one child control and showing another one.
 
Now, I suggest you derive your parent control from System.Windows.Forms.Control, and your child controls implemented modes — from whatever you want. If the implementation of those controls can be overridden by the class user, it's not even your concern. You only provide the interface, write your default implementation with the base class you want, and the user can re-implement it using any other base class.
 
—SA
  Permalink  
Comments
Espen Harlinn at 12-Mar-13 17:26pm
   
If I'm reading you right you are thinking about something like a popup container edit control.
http://documentation.devexpress.com/#windowsforms/clsDevExpressXtraEditorsPopupContainerEdittopic
Sergey Alexandrovich Kryukov at 12-Mar-13 17:41pm
   
As far as I understand, DevExpress in not open-source; that's the only problem. Such "double-mode" control can be well implemented from scratch. If needed.
Thank you,
—SA
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 2

What about overriding
protected virtual CreateParams CreateParams
{
  get {...}
}
You can then modify the Style as needed
 
WS_HSCROLL has a value of 0x00100000L
WS_VSCROLL has a value of 0x00200000L
 
Window Styles[^]
 
Best regards
Espen Harlinn
  Permalink  
Comments
Sergey Alexandrovich Kryukov at 12-Mar-13 17:06pm
   
You see, I think the problem is different. I tried to argue that OP actually needs to use ScrollableControl, not get rid of it; I basically explained some ideas (OP's requrements were vague, that's the problem), so OP does not actually want what she/he thinks she/he wants. Using CreateParams and Windows-specific constants always can become a source for some incompatibility, should be avoided by all means. Pure .NET solution should work...
—SA
Espen Harlinn at 12-Mar-13 17:23pm
   
Overriding CreateParams and modifying the Style property is how you add scrollbars to controls when you use Windows Forms. This is exactly how he did it with Delphi too. Windows Forms and VCL are so similar I find it strange that the similarity isn't mentioned more often.
 
If I'm reading OP right, he should be using WPF which is more flexible, not Windows Forms.
Sergey Alexandrovich Kryukov at 12-Mar-13 17:39pm
   
I know, but CLR is isolated from native OS API. In a ported CLR, your low-level code may not work, that's why it's the best to avoid it...
—SA
Espen Harlinn at 12-Mar-13 17:43pm
   
The Style stuff is implemented in Mono too, they found it easier to simulate many of the 'native' windows elements.
Sergey Alexandrovich Kryukov at 12-Mar-13 18:11pm
   
I know; even some Window messages are simulated, so such Windows-specific, say, message IDs can probably be used on Mono. So actually your code might work even on Mono, I'm not sure. I would be very carefully with anything defined in Windows API and not defined in .NET FCL, isn't that reasonable?..
—SA
Espen Harlinn at 12-Mar-13 18:22pm
   
>> isn't that reasonable?..
Perhaps, but based on experience it has worked out quite well... even IBMs' OpenClass which was 'portable' across AIX, OS/2 and Windows put a bit of work into ensuring that this would work.
Sergey Alexandrovich Kryukov at 12-Mar-13 18:35pm
   
I understand; it needs caution, but really good to know it worked...
—SA

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
0 OriginalGriff 8,149
1 Sergey Alexandrovich Kryukov 7,287
2 DamithSL 5,614
3 Manas Bhardwaj 4,986
4 Maciej Los 4,910


Advertise | Privacy | Mobile
Web03 | 2.8.1411023.1 | Last Updated 4 Mar 2013
Copyright © CodeProject, 1999-2014
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100