WPF ListBox Scrolling Dilemma - c#

I ran into kind of a dilemma with WPF's scrolling behavior in a ListBox:
When I set ScrollViewer.VerticalScrollBarVisibility="Auto" inside the ListBox, scrolling works fine. But clicking on the last half-visible element will move the item up to bring it into view, and the items then are aligned to the top of the topmost item, not the bottom of the lowest one. This is especially annoying when double clicking, as the item will move up under the cursor, and the second click will potentially hit the next element, thus opening the wrong one.
Alternatively, I could put the whole ListBox inside a ScrollViewer. This way, when clicking on the last visible item, the items are nicely aligned to the bottom of this element. But this breaks scrolling using the mouse wheel, and PageDown jumps to the last item instead of one page down.
Is there a way to have ListBox scrolling just work correctly?

To the point one:
Did you try to set ScrollViewer.CanContentScroll="False"?

Related

How to bring an element inside a list view item to the front of the entire app?

Using UWP XAML, I am trying to recreate this textbox UX from Postman whereby it pops up above all other elements in the app to display the full text: https://streamable.com/avrixo. I've almost fully recreated this UX, but I am having trouble bringing the textbox to the "front" of the app while the textbox is inside a listview.
What I have tried:
I have tried creating a UserControl for a custom text box with Canvas as its parent. Like this:
<Canvas>
<TextBox/>
</Canvas
I added some event handling to change the text wrapping and the Canvas.Zindex attached property of the textbox when the user focuses on it (I've tried setting the z-index to 1, 10, 100, and 1000000). However, I found that as the textbox expands vertically, it remains "behind" the listview item below it no matter what z-index I give it.
How can I bring the textbox inside a listview item to the "front" of the UI?
I don't think your problem is with z-index (per say) in this case. The problem here in the ListView is that each ListViewItem has it's own bounds, so the TextBox is being clipped by the bounding box of the item. You can double-check the bounding areas with the Visual Tree tools at least to confirm that's the issue.
If you don't want the ListViewItem to expand in size to match, I can see two options. When the user clicks to edit, you put a 'fake' TextBox (bound to the original in the ListView or the data item) either in 1) a Pop-up that you display or 2) in an overlay that's part of your page's XAML that has the textbox.
You can grab the selection state and cursor positions and such from the original textbox, and move focus to the new one and mirror that same state.
That's the approach I think I'd take.

Continue on the right side when scrollbar is visible

In a checkedlistbox control in C# winforms I can add items into it, however the items will be placed under each other even when the height is smaller than the items combined.
My question is;
Can I "split" the checkedlistbox so you can see everything without having to scroll?
So when the left side is full, it will start on the other half of the checkedlistbox.
What you are looking for is CheckedListBox.MultiColumn property.

Why can I not click a small CheckedListBox?

I have created a CheckedListBox control with 4 elements in C#. Multicolumn is set to true. As soon as I make the height of the control small enough to contain only a single row, I can no longer interact with the control with the cursor when I execute the program. If I make the height one unit (pixel?) larger, so that there are 2 columns of 2 rows, behavior returns to normal.
When the cursor cannot interact with the CheckedListBox, I can still tab to it, toggle between its elements with the arrow keys, and check/uncheck elements with the space bar. I just cannot use the cursor.
Looks like a bug to me... I'm experiencing the same thing occasionally. It happens when (1) the CheckedListBox is 1 row high, and (2) the items in it extend ANY past the right edge of the control. If the control is made a little wider, the mouse clicking works again. (You can test that theory by anchoring the CheckedListBox Left/Right and resizing the form. Now it works, now it don't.)
Seems like setting the width to be total column width + 4 also works.
There is a minimum width such that all columns are fully displayed that must be met before you can interact with it via mouse cursor.

How VerticalOffset changes when Scrollable height changes while having list inside a list

I am making a WP7 app which has a Listbox of UserControls. Each UserControl has an ItemsControl and Button(for getting more results). On click of the button the ItemsControl items will be increased by 5 or 10.
Now on clicking on the GetMore button of any of the usercontrols except the first or last, there will be an increase in Scrollable height(Total height of the listbox) of the ListBox but the VerticalOffset(position of scrollbar from top) of the ListBox remains same. Now the problem I am facing is that the Vertical Offset is not absolute but relative to Scrollable Height. So the content being viewed till then will be changed basing on the new value of ScollableHeight.
I want to know the relation between them, so that I can do some math and set the VerticalOffset value.
I have added some dependency properties on VerticalOffset and ScrollableHeight through which I can get the events when any of them is changed. Trying to use ScrollIntoView for readjusting the Vertical Offset
Any suggestions or corrections are highly appreciated.
I am not able to find the calculation. But what can be done is listbox can be replaced by a scrollviewer which has itemsControl inside it. But the disadvantage of this is virtualisation is disabled, so will need to check on this.
But, overall this is going to give a bad experience on using such a UserControl in Listbox. So using templated list box given in WP7 toolkit is an option but it is gonna hang a bit since ListBox is not optimized for multi templated virtualization. So I started showing writing listbox item template in such a way it contains all the possible layouts which will enabled from a condition.

Scrolling of ListView containing Expanders which contain ListViews does not work

I have the situation that my C# WPF application contains a ListView whose elements are Expanders. Each of those expanders contains a ListView with ListViewItems. Here is a picture:
On the right you can see a Scrollbar. And that ScrollBar is my problem. It has got two issues:
The ScrollBar does not work when using the MouseWheel over the expanded list. By that I mean the area from "Controller" down to "FullInstallation". If hovering over the header ("All Tests"), the ScrollBar does scroll. I think that the ListView inside the Expander by default has a ScrollBar which "steals" the MouseWheel event. However, I don't know what to do against it.
The ScrollBar scrolls over the Expander items and not the content of the expanders. By that I mean, that it is not possible to scroll a little bit down, instead you always scroll at least 1 Expander item down. I would like the scrollbar to scroll such that it is possible to see for instance one half of the "All Tests" Expander.
The picture shows a disabled scrollbar, but by making the window smaller, the scrollbar gets enabled.
What I have tried so far:
ScrollViewer outside the outer ListView: This solves Problem 1, however it means that the MouseWheel does not work at all! That is because the outer ListView generates its own ScrollViewer (used Snoop to find this out) which "steals" the MouseWheel events.
Redirected all the MouseWheel events of all the controls (ListView, Expander, ListViewItem) to the ScrollViewer: Again I used a ScrollViewer outside of the outer ListView and this time I used the MouseWheel event for all my controls to call the MouseWheel event of the outer ScrollViewer. This did work, however for some locations of the mouse pointer it didn't. For instance between two ListViewItems there is a small 1 millimeter space where the MouseWheel event is not catched. Or at the bottom after the last Expander ("Short Tests"). There I do not get any event.
I tried a couple more things but did not get any further.
Does anyone have an idea how to solve this?
Best wishes,
Christian
1) For how to write an attached behavior to control mousewheel behavior when you have nested itemscontrols, see: WPF Nested ScrollViewer / ListBox Scrolling
2) Non virtualized itemscontrol supports smooth scrolling, see: Is it possible to implement smooth scroll in a WPF listview?

Categories