开发者

WPF expand TreeView on single mouse click

开发者 https://www.devze.com 2023-02-14 16:32 出处:网络
I have a WPF TreeView with a HierarchicalDataTemplate. Currently I have to double click an item to expand/collapse it.

I have a WPF TreeView with a HierarchicalDataTemplate.

Currently I have to double click an item to expand/collapse it.

I wou开发者_StackOverflow中文版ld like to change this behaviour to a single click, without loosing other functionality. So it should expand and collapse on click.

What is the recommended way to do this?

Thanks!


You could use a re-templated checkbox as your node (containing whatever template you are currently using) with its IsChecked property bound to the IsExpanded property of the TreeViewItem.

Here is a template I've just test that seems to do the job:

<HierarchicalDataTemplate ItemsSource="{Binding Items}">
    <CheckBox IsChecked="{Binding RelativeSource={RelativeSource AncestorType=TreeViewItem}, Path=IsExpanded}">
        <CheckBox.Template>
            <ControlTemplate>
                <TextBlock Text="{Binding Header}"></TextBlock>
            </ControlTemplate>
        </CheckBox.Template>
    </CheckBox>
</HierarchicalDataTemplate>

Just replace the ControlTemplate contents with whatever you need.


If you are using a standard TreeViewItem, then you can capture the click event:

private void OnTreeViewMouseUp( object sender, MouseButtonEventArgs e )
{
    var tv = sender as TreeView;
    var item = tv.SelectedItem as TreeViewItem;

    if( item != null )
        item.IsExpanded = !item.IsExpanded;

    e.Handled = true;
}

private void OnTreeViewPreviewMouseDoubleClick( object sender, MouseButtonEventArgs e )
{
    e.Handled = true;
}

Most likely in your case, you'll need to do something with your binding and ViewModel. Here's a good article from CodePlex: Simplifying the WPF TreeView by Using the ViewModel Pattern.


Just use selected item changed event and use the following,

private void treeview_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
    {
        TreeViewItem item = (TreeViewItem)treeview.SelectedItem;
        item.IsExpanded = true;


    }

where treeview is the name of your TreeView, you could include an if to close/open based on its current state.


I have very little experience working with WPF to this point, so I am not 100% certain here. However, you might check out the .HitTest method of both the Treeview and TreeView Item (the WPF Treeview is essentially the Windows.Controls.Treeview, yes? Or a derivation thereof?).

THe HIt Test method does not always automatically appear in the Intellisense menu for a standard Windows.Forms.Treeview (I am using VS 2008) until you type most of the method name. But it should be there. You may have to experimnt.

You can use the .HitTest Method to handle the MouseDown event and return a reference to the selected treeview item. You must test for a null return, however, in case the use clicks in an area of the control which contains no Tree Items. Once you have a reference to a specific item, you should be able to set its .expanded property to the inverse of whatever it is currently. again, some experimentation may be necessary here.

As I said, I have not actually used WPF yet, so I could have this Wrong . . .


The answer of Metro Smurf (thanks to which I got where I wanted to be) suggests the right approach . You could simply hook up to the SelectedItemChanged event of the Treeview. Then cast the e.NewValue passed in the eventhandler as TreeViewItem, and access its IsExpanded property to set it to true.

void MyFavoritesTreeView_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
{
    ((TreeViewItem)e.NewValue).IsExpanded = true;
}

Then for the final touch, you can also hook up the items in your Treeview by casting them as TreeViewItem as suggested, and then you can hook up to the various manipulation events, like:

var item = tv.SelectedItem as TreeViewItem;
item.Expanded += item_Expanded;

And then do whatever you need to do in the eventhandler

void item_Expanded(object sender, RoutedEventArgs e)
{
// handle your stuff
}
0

精彩评论

暂无评论...
验证码 换一张
取 消