2

I have a listview whose item template is a treeview( having fixed height and width). Not much xaml or code to post .

Now I can scroll the list if the mouse is not over the TreeView. How can I scroll the list even if the mouse is over any TreeView?

KhannaB7
  • 265
  • 5
  • 17
  • Perhaps duplicate of - http://stackoverflow.com/questions/14348517/child-elements-of-scrollviewer-preventing-scrolling-with-mouse-wheel – Spawn Nov 24 '15 at 15:26
  • @Spawn I think the link will solve OPs question, however not sure it would be a duplicate. New WPF'ers would be more likely to stumble upon this question when running into the same problem than knowing to search for scrollviewers and child elements. I'd upvote your answer if you said the same thing. Bonus points if you provide working XAML :) – Kcvin Nov 24 '15 at 15:30
  • @NETscape I've ask "scroll wpf when cursor on another scrollable" to get link on that question :) – Spawn Nov 24 '15 at 15:50
  • I had looked at the control template of tree view , I figured that if I remove the scroll viewer then the scroll event bubles from itemsPresenter to the listview and the scroll take place as desired. (Obviously the items in the tree view won't scroll then so would need to handle that items in treeview are all visible). – KhannaB7 Nov 26 '15 at 07:19
  • Both answers from spawn and mr.lb work. – KhannaB7 Nov 26 '15 at 07:20

2 Answers2

2

We can solve this with some behavior. Simple example:

Behavior with comments:

public sealed class ScrollParentBehavior : Behavior<UIElement>
{
    protected override void OnAttached()
    {
        base.OnAttached();
        AssociatedObject.PreviewMouseWheel += AssociatedObjectOnPreviewMouseWheel;
    }

    protected override void OnDetaching()
    {
        AssociatedObject.PreviewMouseWheel -= AssociatedObjectOnPreviewMouseWheel;
        base.OnDetaching();
    }

    private void AssociatedObjectOnPreviewMouseWheel(object sender, MouseWheelEventArgs e)
    {
        // find parent, it will be ContentPresenter
        var parent = VisualTreeHelper.GetParent(AssociatedObject) as UIElement;
        if (parent == null) return;
        // handle event

        // We can create here some logic, if we need to scroll TreeView content

        e.Handled = true;
        // raise it on parent
        parent.RaiseEvent(new MouseWheelEventArgs(e.MouseDevice, e.Timestamp, e.Delta)
        {
            RoutedEvent = UIElement.MouseWheelEvent
        });
    }
}

And usage - ListView and TreeView in ItemTemplate.

<ListView ItemsSource="{Binding}">
    <ListView.ItemTemplate>
         <DataTemplate>
              <TreeView Width="100" Height="100">
                  <i:Interaction.Behaviors>
                      <local:ScrollParentBehavior />
                  </i:Interaction.Behaviors>
              </TreeView>
         </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

Don't forget about xmlns for XAML:

xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"

And System.Windows.Interactivity in references.

Spawn
  • 935
  • 1
  • 13
  • 32
1

You can set IsHitTestVisible="False" for TreeView. Simple example:

<Window x:Class="WpfApplication6.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <ListView Margin="10" x:Name="lvDataBinding" >
        <ListView.ItemTemplate>
            <DataTemplate>
                <TreeView IsHitTestVisible="False">
                        <TreeViewItem Header="{Binding Id}" />
                    <TreeViewItem Header="{Binding Name}" />
                    <TreeViewItem Header="{Binding Details}" />
                </TreeView>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
</Grid>

 public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        List<User> users = new List<User>();
        users.Add(new User() { Id = 1, Name = "John Doe", Birthday = new DateTime(1971, 7, 23) });
        users.Add(new User() { Id = 2, Name = "Jane Doe", Birthday = new DateTime(1974, 1, 17) });
        users.Add(new User() { Id = 3, Name = "Sammy Doe", Birthday = new DateTime(1991, 9, 2) });
        users.Add(new User() { Id = 4, Name = "Sammy Doe1", Birthday = new DateTime(1991, 9, 2) });
        users.Add(new User() { Id = 5, Name = "Sammy Doe2", Birthday = new DateTime(1991, 9, 2) });
        users.Add(new User() { Id = 6, Name = "Sammy Doe3", Birthday = new DateTime(1991, 9, 2) });
        lvDataBinding.ItemsSource = users;
    }
}

public class User
{
    public int Id { get; set; }

    public string Name { get; set; }

    public DateTime Birthday { get; set; }

    public string Details
    {
        get
        {
            return String.Format("{0} was born on {1} and this is a long description of the person.", this.Name, this.Birthday.ToLongDateString());
        }
    }
}
Luke Le
  • 728
  • 1
  • 9
  • 24