0

I am trying to get a TreeView that has multiple selection. I have to build the TreeView programmatically (I assume), as I am getting the data from a Database.

My problem is shown here as I can't embed pictures yet.

The program works as intended in situation A, where I hover the TreeView - I am able to scroll up and down. That is however not possible in situation B, where I'm hovering the ListBox.

The XAML for the example is as follows:

<Window x:Class="WPF_test_1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="150" Width="230">

    <Grid>
        <TreeView x:Name="treeView" Margin="10,10,10,9.8"/>
    </Grid>
</Window>

And the C#:

using System.Windows;
using System.Windows.Controls;

namespace WPF_test_1
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            ListBox lb = new ListBox();
            lb.Items.Add("Test with a long name");
            lb.Items.Add("Test");
            lb.Items.Add("Test");
            lb.Items.Add("Test");
            lb.Items.Add("Test");
            lb.Items.Add("Test");

            lb.SelectionMode = SelectionMode.Extended;
            lb.BorderThickness = new Thickness(0);

            TreeViewItem lv = new TreeViewItem();
            lv.Header = "TEST";
            lv.Items.Add(lb);
            treeView.Items.Add(lv);
        }
    }
}

I choose to add a ListBox to the TreeViewItem, as that enables the multiple selection without having to implement an extension to the TreeView - but as I said, it does not allow me to scroll properly.

Does anyone know a workaround, or what the problem might be?

Thank you in advance.

T.Palludan
  • 176
  • 1
  • 2
  • 13

1 Answers1

0

Now that I've actually got it through my skull what the actual problem is, I found a way to disable scrolling on a ListBox.

Here's a pure-XAML quickie demonstrating the technique on a group of listboxes as children of TreeViewItems.

In pure code-behind, generating a template is a bit of a hassle. I would suggest creating the style in XAML, giving it x:Key="NonScrollingListBoxStyle", and loading it with FindResource("NonScrollingListBoxStyle") in your codebehind. Then you could manually apply it to each ListBox. Here I've made it an implicit style, just to save typing.

<TreeView Height="120">
    <TreeView.Resources>
        <Style TargetType="ListBox" BasedOn="{StaticResource {x:Type ListBox}}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="ListBox">
                        <ItemsPresenter />
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </TreeView.Resources>
    <TreeViewItem IsExpanded="True" Header="Item 1">
        <ListBox>
            <TextBlock>Item A</TextBlock>
            <TextBlock>Item B</TextBlock>
            <TextBlock>Item C</TextBlock>
            <TextBlock>Item D</TextBlock>
            <TextBlock>Item E</TextBlock>
        </ListBox>
    </TreeViewItem>
    <TreeViewItem IsExpanded="True" Header="Item 2">
        <ListBox>
            <TextBlock>Item A</TextBlock>
            <TextBlock>Item B</TextBlock>
            <TextBlock>Item C</TextBlock>
            <TextBlock>Item D</TextBlock>
            <TextBlock>Item E</TextBlock>
        </ListBox>
    </TreeViewItem>
    <TreeViewItem IsExpanded="True" Header="Item 3">
        <ListBox>
            <TextBlock>Item A</TextBlock>
            <TextBlock>Item B</TextBlock>
            <TextBlock>Item C</TextBlock>
            <TextBlock>Item D</TextBlock>
            <TextBlock>Item E</TextBlock>
        </ListBox>
    </TreeViewItem>
    <TreeViewItem IsExpanded="True" Header="Item 4">
        <ListBox>
            <TextBlock>Item A</TextBlock>
            <TextBlock>Item B</TextBlock>
            <TextBlock>Item C</TextBlock>
            <TextBlock>Item D</TextBlock>
            <TextBlock>Item E</TextBlock>
        </ListBox>
    </TreeViewItem>
</TreeView>
  • I don't have a lot of experience in WPF yet, as this is a learning project for me. So I don't know the possibilities of MVVM and XAML. Will it be possible to avoid doing it "programmatically" - even though I know nothing about the amount of ListBoxes and TreeViews I will need? – T.Palludan Jul 12 '17 at 19:22
  • I checked your solution. It adds kind of a nested scrollbar - that's not really intended behavior. Would it be possible to make it so the ListBox is as tall as it needs to be, and still scroll? Like the scroll behavior you have in the File Explorer sidebar. – T.Palludan Jul 13 '17 at 12:03
  • You want scrolling without a scroll bar? I gave you what you said you wanted. Please show me an image of what you actually want. – 15ee8f99-57ff-4f92-890c-b56153 Jul 13 '17 at 12:04
  • You can see the scrolling in the left side menu of [this picture](https://screenshots.en.sftcdn.net/en/scrn/130000/130497/ipad-file-explorer-18.jpg). That's the scrolling I intended for. I'm sorry if that wasn't clear. – T.Palludan Jul 13 '17 at 17:10
  • Nothing is clear. You want scrolling and you don't want scrolling. I'm not a zen master. Good luck. If you can show me *an image **of what you actually want***, I can show you how to create it. What I can't do is guess what it is about that Windows Explorer screenshot that you want to see in your own UI. I see a scrollbar. But you don't want one. OK, whatever. – 15ee8f99-57ff-4f92-890c-b56153 Jul 13 '17 at 17:12
  • Draw a wireframe in pencil on a post-it note if you have to. It doesn't have to be beautiful. It has to communicate what control should have a scrollbar and what control shouldn't. – 15ee8f99-57ff-4f92-890c-b56153 Jul 13 '17 at 17:16
  • I'm on my way out, so I will try with another example first, and if that doesn't help I'll try with the post-it note. Try adding: ListBox lb2 = new ListBox(); lb2.Items.Add("Test with a long name"); lb2.Items.Add("Test"); lb2.Items.Add("Test"); lb2.Items.Add("Test"); lb2.SelectionMode = SelectionMode.Extended; lb2.BorderThickness = new Thickness(0); lb2.Height = 60; TreeViewItem lv2 = new TreeViewItem(); lv2.Header = "TEST2"; lv2.Items.Add(lb2); treeView.Items.Add(lv2); Tbc. Can't seem to format code properly... – T.Palludan Jul 13 '17 at 17:24
  • You'll now have two treeViewItems (and 3 vertical scrollbars) and can't scroll to the second one when you hover over the first ListBox. I only want one scrollbar attached to the treeview. – T.Palludan Jul 13 '17 at 17:25
  • @T.Palludan If you just refrain from setting a fixed height on any of the listboxes, does that do what you want? If that's the case, I wish you hadn't mentioned the listboxes at all. – 15ee8f99-57ff-4f92-890c-b56153 Jul 13 '17 at 17:26
  • Incidentally, I assumed you had some reason for using the listboxes, but now I wonder. Are you using listboxes only to provide the treeview items with children? `TreeViewItem` has an `Items` property for that. – 15ee8f99-57ff-4f92-890c-b56153 Jul 13 '17 at 17:29
  • I'm using ListBoxes to get their multiple selection behavior. But they're there as the items for the TreeViewItem, yes. It behaves as I want when I'm not setting a fixed height. That's similar to my picture in my OP - as long as I do not hover the ListBox area as shown in situation B. When my mouse is in that position I can't use the scrollwheel to scroll up and down. That's my problem. – T.Palludan Jul 13 '17 at 21:08
  • @T.Palludan Ohhhh. OK, I finally get it. Thanks for being patient. Let me look into this. – 15ee8f99-57ff-4f92-890c-b56153 Jul 13 '17 at 21:31
  • I thank you a ton for having patience with me! That really helped me. A great solution that doesn't require rewriting TreeViewItem and implementing multiple selection that way - as I've seen other solutions do. Thank you! – T.Palludan Jul 14 '17 at 05:41