WinForm Panel scrolling without a scrollbar? - winforms

I'm creating a User Control that's basically a Panel (with random content inside), and I need to be able to scroll up and down this Panel using buttons (up and down) rather than the scrollbar.
The reason I have to do it this way is because the program will be used on a touch screen monitor and we need big buttons rather than an ugly little scrollbar.
I've been messing around with the VerticalScrollbar properties, and none of them seem to do anything. I've noticed that if I set AutoScroll to false, AutoScrollPosition actually shows coordinates, except negative of what it should be. Also, I've noticed that panel.VerticalScrollbar.Visible = true; only seems to work when placed outside of the constructor. Is there a reason for that?
Basically, WinForms' scrollbars are very confusing (buggy?) to me. Does anyone know a good way to scroll up and down a panel programmatically with buttons (I don't care if I need to have an invisible scrollbar).
Thank you! =D

Make your UserControl a regular UserControl (i.e inherit from UserControl instead of Panel) and place a Panel on your UserControl. Put any content/controls on the inner Panel, and then change the Panel's Left and Top properties to move it around without scrollbars. You could also add buttons to your UserControl to handle the movement of the inner Panel.
A simpler way, however, might be to just use really wide/high scrollbars, and set their Thumbwidth (I think this is the property) to the same large value - this will produce scrollbars that are easy to use with the fingers. To my knowledge there's no way to do this with the scrollbars that appear on a Panel with Autoscroll set to True, so you'd still need to use the method I mentioned above (with an inner Panel sitting on your UserControl) and add the scrollbars to move it yourself.
I agree that scrollbars in Windows suck, so while I'm normally in favor of just using the standard controls that everyone is used to, I don't see anything wrong with rolling your own in this case.

Related

programmatically making a dropdown menu in vb.net WPF

I'm making a custom dropdown button (since the one included in wpf requires too much hacking to style right). Now that i got the button bit out of the way i need to add the drop down part.
My first thought was to add a stackpanel and use that to contain the items but it gets cut off if it leaves the borders of the grid that the button is in. Next up was the popup primitive, it gets on top of everything nicely enough but position wise it just free floats and i haven't figured out how to make it follow the button it was spawned by. I also tried using contextmenu but that seems to have no positioning controls at all and just sits where the mouse made it..
Anyways wpf is a big package and I'm just getting into it, anybody know which direction i might find what I'm looking for?
Preferred approach normally is to use a Popup. You got two very important properties with a Popup
PlacementTarget and Placement
Setup a binding for PlacementTarget on the Popup to your custom Button and then use Placement to position the Popup accordingly w.r.t to the PlacementTarget(Button)
Placement accepts an enum of type PlacementMode which gives you quite a few options to position the Popup.

Can we overlay a WPF element by another?

I've this situation:
A label placed in Footer Cell of a RadGridView doesn't have sufficient width available in its container for displaying its full text.
Is it possible by any ways to have the label cross its container boundaries and show full text?
Thanks!
The space given to any element depends on the parent control or Panel that contains it, as well as its Width, Height, Horizontal and VerticalAlignment, and Margin. Normally you can manipulate some combination of these directly to change overlapping behavior but by using a DataGrid control you've given up a lot of that control since things like ColumnSpan are set up by the control internally. You could try setting negative Margin values and changing the Panel.ZIndex but I doubt those will help.
The best solution I can recommend without more detail is to use TextWrapping or TextTrimming to avoid ugly clipping, maybe in combination with a ToolTip showing the full text.
You can overlay any WPF element by another anytime. Only place where it fails is the WebBrowser control .The WPF WebBrowser has not been improved a single bit from WinForms WebBrowser. It is still the same simple activex control. However, you can bypass even that with a tooltip control.
I believe you can either set ClipToBounds=False to allow it to expand outside its area, or set TextWrapping=Wrap to allow the text to wrap.
EDIT: Forgot ClipToBounds is only honored in the Canvas control, so wrap your label in a Canvas and set ClipToBounds=False and it should work.

WPF ListBox does not realise that its items have changed size

I have a ListBox that contains a number of User items that are DataTemplated to appear as UserControls in the ListBox. Each UserControl can be expanded in size. To start with, the ListBox is big enough to display them all in their unexpanded state. The problem that I have is that when a number of these UserControls are expanded together, they extend out of the ListBox's visible area. The ListBox does not recognise this fact and no ScrollBars appear, even when they are set to Visible.
I am using DoubleAnimations to alter the UserControl heights when the user clicks on a button in each one. Is there something that I have to do, or some setting on the ListBox that must be set to get it to register the size changes of the UserControls that represent its items and display ScrollBars when needed?
Edit>>>
I have tracked down the problem to a custom WrapPanel that I am using in the ListBox.ItemsPanel. When I remove it, or replace it with a standard WrapPanel, ScrollBars appear when required. I got the code for the Panel from a good article about creating custom WPF panels. Can anyone see what's missing from the code given in the article and why it might stop the ScrollBars from displaying?
I wonder whether ListBoxes normally do what you are expecting? You might try calling InvalidateMeasure/Layout on the ListBox if you know when the item sizes change, just to see?
I decided to write the custom WrapPanel code again completely and this time it worked correctly! When comparing the new version with the previous version, I could see that a + was missing from a += in a measuring calculation and so the Panel thought that the items were much smaller than they really were... hence no ScrollBars.
So, if you have this problem, check your measuring code carefully.

Is it possible for WinForm controls (Panel,etc.) to grow like a webform control?

I'm converting an app from ASP.NET WebForms to WinForms. There is one asp.net page which contains a ListView/Repeater that contains several custom controls, which in turn contain a ListView with other custom controls. Basically the layout looks like a TreeView, but on each node/leaf there are few controls like comboboxes, etc.
When this is in ASP.NET, the page automatically lays itself out, so it is several screens tall - if I add 20 buttons into a Panel, it will grow and the browser will get scrollbars.
I'd like to do the same thing in a WinForms application - so I'll have a user control that will contain a lot of controls in a some variation of Panel (Flow, Table layout), and the controls might have another controls inside them, etc.
The problem is, that when I make winforms app, each control has specific height in the design time. I'd like some user controls to be able to grow with their contents - so they'll add up. In the main Form, there should be a vertical scrollbar, just like in the web browser when the generated page is taller than the screen.
I'd just like to get some general pointers in the right direction. Thanks.
Use Anchor and Dock container properties.
Yes, to expound on Anchor and Dock...try this
-Place a Panel on an empty form, and set its dock property to Top
-place a textbox in the panel, and Dock it to Full...it should fill the whole top panel
-Place a splitter on the form, and if not already docked correctly, set its dock to top
-place another panel below the splitter, and set its Dock to Fill
-place another textbox inside the lower panel and fill it as as well
Now you have a form with two resiable textboxes and will resize when the form does.
*you may have to set the textbox MultiLine property to true but not sure.
Hope this helps.
Anchor the controls to the parent. Anchoring all four sides will cause it to stretch.
If the Anchoring and Docking answers don't work for you, there is another option. It's not pretty, but you can access a control's properties and change them dynamically during runtime. You'd do something like: if(listBox.Items.Count > [yourVal]) listBox.height = [yourFormula] or something.
It's been a while since I've done a Win Form (and I don't have my IDE fired up at the moment) but I'm pretty sure there's even a ScrollPanel or other scrolling control that you can set on your form.
That said, when you're working with WinForms, the less scrolling you can make your users do, the better.

How can I animate show/hide of an item in an ItemsControl, but only animate if the window is already visible?

I have an ItemsControl with a number of elements, each one with its own ViewModel instance. Each item's ViewModel knows whether that item should be visible (currently each ViewModel has a Visibility property that the UI binds to). When my window first opens, some of these items are visible, others are collapsed. Later, some items' visibility might change in response to user interaction. The window sizes to its content, so the window resizes when items are shown or hidden. And the window is initially centered on the screen (which means everything has to be arranged properly right away, so the window knows its initial size and can center itself accordingly).
Now I want to add animations whenever an item is shown or hidden -- but I only want to animate if the item's visibility changes after the window is already shown. So if the window is already open, and the user does something that makes one of the ViewModels want to appear, it animates in; if the user does something to make one of the ViewModels disappear, it animates out. But when the window first opens, I want everything to start out rock-solid -- no lingering animations.
And I want the window to still set its initial size based on its initially-visible content, and I still want it to be initially centered onscreen. (Although actually, in this case, it would be acceptable if it centered itself as if all items were visible, if event ordering made it work out that way.)
I know a fair bit about WPF, but I admit I'm lost when it comes to triggers and storyboards. I haven't really done anything with WPF animations before, and I'm not sure where to begin.
I already tried using Reveal from the Bag of Tricks, but I had several problems with it, the biggest being that it doesn't have the "only use animations after the window is shown" behavior that I want -- my window would appear and the initially-visible elements would still be animating in. It also didn't play well with my layout (it was centering the elements horizontally, instead of stretching them to the ItemsControl's width), and a few other problems that might or might not be fixable.
I'm not too picky about whether I animate by stretching (e.g. by animating a LayoutTransform from SizeX=1 SizeY=0 to SizeX=1 SizeY=1, thus starting with squished text and expanding to normal size) or by just changing the Height (thus starting with only part of the content visible and revealing more as the animation progresses) -- I'm fine with either.
I'm open to writing my own Panel descendant (I've done it before) if that's the best way to solve this, and I can always steal code from Reveal and hack until I get it working -- but it seems like there should already be an easier way to do this, if I just knew what it was. I'm open to learning about triggers and storyboards, or whatever, if someone can point me in the right direction.

Resources