Header control in WinForms - any such thing? - c#

I'm trying to use the windows native (Theme-aware) header control to display just some column headers. The main purpose is to avoid manually drawing the column headers and rely on the natively supported functionality.
So the 2 options I was thinking of are:
Use a HeaderControl, and add columns to it (I can't seem to find a header control supported by WinForms).
Use a ListView control, and tell it display no rows (or basically set its height to the height of the column header) - can't find any way to determine which height should I assign to the control.
Any good ideas much appreciated!

There is no HeaderControl for WinForms in the .NET framework so far (the ListView utilises the ColumnHeader class but this is only useful with the ListView). If you are only targetting Microsoft Windows, you could look at wrapping the Win32 control for use in .NET although I expect that will be substantial work.
Your second option is a valid possibility even though it feels somewhat clunky. I can see difficulties arising in getting the list to size properly such that the header and only the header is visible.
A third option would be to roll your own HeaderButton that represents one column (like ColumnHeader) and use the theme drawing calls to draw it, then just combine them in a FlowLayoutPanel or TableLayoutPanel into your header bar. If you want resizing, you could make the HeaderButton have a grab region that you can pick up and alter its width.
I think the third option will be reasonably simple to create, even with the sizing ability, so I would recommend taking that route (I might even give it a go myself when I get home tonight).

Related

Alignment of text when column width is changed from GUI in winform application

I have developed a winform application. It has a listview with multiple columns having different texts. Initially, I have set the column width = -2 to take the size of longest text in the column.
The issue is that sometime text overshoots the laptop screen and a horizontal scroll bar appeared in the list view.
To fit all the columns in a screen, I manually modified the columns widths using column boundaries in the GUI. When I modify the column width, the column text starts disappearing from right. I want it to disappeared from left.
I have searched goggle a lot but did not find the answer.
Question might look weird or may be I have not explained it properly. Please let me know if more information is needed.
Thanks in advance.
The Listbox columns in Windows Forms are not exactly a high level control, I've used it some times but just for simple lists, It certainly has not a builtin function to make what you want, to obtain it you probably need to subclass the control, create a new class for the item managed in the list and write some code to perform what you need.
I think you can find some hints on how to achieve all this in Charles Petzold book about windows forms where he shows how to measure a string and how to draw directly on your control.

WPF Wrapping content into maximum 2 columns. Evenly distributed

I am attempting to insert a panel into my WPF application that would have a few very specific behaviours:
1.) Wraps content evenly. Starting from the top left corner and running downward, before moving to the next column.
2.) Allows me to define a maximum number of columns to wrap to. For my purposes, this number would be between 1 and 3.
3.) Allows me to set an initial height, but it will also grow to accommodate additional items. (Only setting an initial height because my content won't wrap without it. If I leave it auto, it all comes out in a single column regardless of whether it fits on screen or not)
At this point, I have concluded that what I'm attempting do will require a custom panel, but I'd like to ensure before I begin that process (and learning how to do so) that I'm not missing a much simpler answer.
A WrapPanel can be set to wrap vertically, but you have no control over the number of columns.
A UniformGrid would offer you control over the number of columns, but wraps horizontally not vertically.
In short: you need a custom panel. The built-in ones do not offer the combination of features that you want.
UniformGrid has a LayoutTransform property, which can be used to transform it in order to change the position/rotation of the elements inside. But it will also transform the content.
Some more tricks involving Setters on the types of the items inside your UniformGrid and the content can be transformed again to retain the desired "original" orientation.
You can learn more in this tutorial.
Alternatively, it seems that the Extended WPF Toolkit contains its own implementation of UniformGrid, with an Orientation property, the only problem being that it won't grow to accomodate the number of items; instead, it will obey to an arbitrary Columns property.
Then again, you may be able to change the value of this property each time you add a new item/resize your UniformGrid, but it will be some more manual work and may potentially lead to code behind, which could be seen as an issue if you're working in MVVM.

ListView auto size to show all items

What I want to create is a list view that will resize itself in order to show all items. Normally I would use AutoSize, but this won't work here. Any other options how can I make ListView expand and shrink to fit all?
You will have to manually calculate your desired height and set it as items are added/removed.
Detecting item addition or removal isn't directly supported - so you'll either need to create your own Add/Remove Item calls for clients to call, or handle LVN_INSERTIEM type messages from WndProc.
Auto-sizing controls are usually trickier to use - as you have to track Min/Max sizes, allow room on the owner, and usually add to an awkward usability point for users. Only do something like this if typical solutions (i.e. scroll bars) truly can't work for your need.
"AutoSize" property is not supported for the "ListView" control. As #JohnArien mentioned, you will have to programmatically re-size your list view control's size according to the number of items available. But be warned that this may not be a good idea in terms of visual appeal of the Form. Your form design might look ugly if you change the size in run time. More over these types of controls are expected to expand their client area within the given size with the help of scroll bars. I would strongly suggest you to reconsider this option.

WPF Control Questions

I just switched over to WPF from just regular C# .NET for the more advanced UI design controls. I have managed to become extremely confused over what should be extremely simple, and I hope someone can help.
Basically I want to have sections on either side (for the most part these will be list-boxes inside of expanders), one list-box in the bottom-middle, and then a large rich text box taking up the middle.
My understanding was that I could just take a DockPanel, set the ChildFill to true, dock each one where it should go, and leave the last one to fill the space. The list boxes alone don't seem to work at with the DockPanel, and the DockPanel does not seem to expand when I change the size of the window.
So basically my questions are...
1) Why does the DockPanel not expand/shrink when I change the size of the window?
2) Buttons seem to work fine in the Dock Panel (like all of the examples I found) but using List Boxes instead does not seem to work properly. Why is this?
3) If I put the list boxes inside of Expanders instead, if I have say two of these on the left side, and I shrink the top expander, will the bottom expander grow upwards to fill the gap?
I can't really afford anything like ActiPro, and I was not able to get the AvalonDock controls to show up on the MSVC 2010 toolbar, so I am pretty much stuck using the default controls.
1). I have just tested the DockPanel and it does expand / shrink when the Window is resized - Have you removed the Grid that is placed in the Window by default in Visual Studio? If you mean it doesn't resize proportionally to the Windows size then i think you will need to use a Grid.
2). Again, list boxes work fine for me - Can you provide some more detail explaining why they don't work properly?
3). It depends on what you mean by "Grow upwards". If the top expander is closed, only the header will be displayed and the bottom expander will move up to take the space taken by the first expanders content (this is the default behaviour).
Do you have some XAML you can post as this will help identify your problems.

How do I know when the current system scrollbar width changed?

I need to move controls around when the scrollbar's size change (System.Windows.Forms.SystemInformation.VerticalScrollBarWidth).
I'm creating a control with custom scrollbars that go over the normal ones. This implies creating a new UserControl (not inheriting a built-in control) and playing around with panels so as to hide the normal scrollbars.
The custom control must have one "outer" panel at the right size, this one containing an "inner" panel larger than the outer panel, so the scrollbars do not appear. How much larger depends on System.Windows.Forms.SystemInformation.VerticalScrollBarWidth and HorizontalScrollBarHeight as was already answered. But then I must know if that changes when my app is running, as improbable as it seems.
This question is related to:
How do I know the current width of system scrollbar?
I'm currently trying to achieve something similar.
I'm running Windows XP SP3, "Classic" style, and upon changing just the scrollbar width of the current design, my override of OnSystemColorsChanged() (in a class derived from Control) gets called four times.
Why it's four times I don't really know, I suspected it might be because there's four properties in there that seem to depend on that setting:
SystemInformation.HorizontalScrollBarArrowWidth
SystemInformation.HorizontalScrollBarHeight
SystemInformation.VerticalScrollBarArrowHeight
SystemInformation.VerticalScrollBarWidth
But all of these already hold the new value at time of the first call. So I'm not 100% sure what's going on here. But it looks like OnSystemColourChanged() should rather be called OnSystemInformationChanged().
Hope this helps ...
One must listen to Microsoft.Win32.SystemEvents.UserPreferenceChanged.
As takrl mentioned, OnSystemColorsChanged gets called, but only once for me (Windows7, Framework 3.5)

Categories

Resources