lpx

Hi,

I want to be able to reproduce the normal behaviour when we click a treeview with the right button, this is, it gets selected and the context menu opens.

What i really don't know how to do it is selecting the item automaticly...

Can somebody give me lights here

Thx,

Nuno



Re: Windows Presentation Foundation (WPF) How to select an item in a TreeView, clicking in the right button?

Benny Tops

Hi,

You could implement the MouseDown event and check in the MouseButtonEventArgs if the right button was clicked. If that's the case, select the item.

Best regards,

Benny





Re: Windows Presentation Foundation (WPF) How to select an item in a TreeView, clicking in the right button?

lpx

I'm sorry but i think i didnt understood your tip.

See if the right button was clicked its easy, but.. how can i see if the mousedown catched an element

I cant see how can i get a possible selected item the way you suggest.

I have seen technics for doing this before, in .net 2.0. It consisted in getting the mouse point and then try to see if that point corresponded to an element in the treeview.

Can you give me a code snippet





Re: Windows Presentation Foundation (WPF) How to select an item in a TreeView, clicking in the right button?

Benny Tops

Hi,

Yes, I can. A code snippet:

Code Snippet

<Window x:Class="Sample.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Sample" WindowState="Maximized" x:Name="window"
>
<Grid>
<TreeView x:Name="treeview">
<TreeViewItem Header="TreeViewItem1"></TreeViewItem>
<TreeViewItem Header="TreeViewItem2">
<TreeViewItem Header="TreeViewItem3"></TreeViewItem>
<TreeViewItem Header="TreeViewItem4">
<TreeViewItem Header="TreeViewItem5"></TreeViewItem>
<TreeViewItem Header="TreeViewItem6"></TreeViewItem>
</TreeViewItem>
</TreeViewItem>
<TreeViewItem Header="TreeViewItem7"></TreeViewItem>
<TreeViewItem Header="TreeViewItem8"></TreeViewItem>
</TreeView>
</Grid>
</Window>

public partial class Window1 : System.Windows.Window
{

public Window1()
{
InitializeComponent();
//Attach Mouse Down handler
foreach (TreeViewItem item in treeview.Items)
{
AttachMouseDown(item);
}

}

private void AttachMouseDown(TreeViewItem item)
{
item.MouseDown += new MouseButtonEventHandler(item_MouseDown);
if (item.Items.Count != 0)
{
foreach (TreeViewItem childitem in item.Items)
{
AttachMouseDown(childitem);
}
}
}

void item_MouseDown(object sender, MouseButtonEventArgs e)
{
TreeViewItem item = e.Source as TreeViewItem;
if (e.RightButton == MouseButtonState.Pressed)
{
item.IsSelected = true;
MessageBox.Show(String.Format("{0} has been right clicked!",item.Header));
}
}
}



Best regards,

Benny





Re: Windows Presentation Foundation (WPF) How to select an item in a TreeView, clicking in the right button?

lee d

you can just an an event handler on the treeview

void Window3_Loaded(object sender, RoutedEventArgs e)

{

treeview.AddHandler(TreeViewItem.MouseDownEvent,new MouseButtonEventHandler(tvi_MouseDown));

}

void tvi_MouseDown(object sender, MouseButtonEventArgs e)

{

TreeViewItem item = e.Source as TreeViewItem;

if (e.RightButton == MouseButtonState.Pressed)

{

item.IsSelected = true;

MessageBox.Show(String.Format("{0} has been right clicked!", item.Header));

}

}






Re: Windows Presentation Foundation (WPF) How to select an item in a TreeView, clicking in the right button?

lpx

This doesnt work.

Now, every time i click in the right button it selects me the base node... Tongue Tied

This is what i have:

Code Snippet

In my window.xaml.cs

tvNetworkExplorer.AddHandler(TreeViewItem.MouseDownEvent, new MouseButtonEventHandler(ne.tvNetworkExplorer_MouseDown));
tvNetworkExplorer.SelectedItemChanged += new RoutedPropertyChangedEventHandler<object>(ne.tvNetworkExplorer_SelectedItemChanged);

In another file:

public void tvNetworkExplorer_MouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
TreeViewItem item = e.Source as TreeViewItem;
if (e.RightButton == MouseButtonState.Pressed)
{
item.IsSelected = true;
}
}



Whats wrong

Nuno





Re: Windows Presentation Foundation (WPF) How to select an item in a TreeView, clicking in the right button?

lpx

Thx for the code snippet. It works, but not on my Tree Tongue Tied

I have tried your code stand alone and it works.

I made the same thing in my context and it doesnt work. Really strange.

Any clue

Thx,

Nuno




Re: Windows Presentation Foundation (WPF) How to select an item in a TreeView, clicking in the right button?

lpx

Hi,

I'm having a problem with this. With the code that Benny provided everything works perfectly, but the Tree is also a perfect tree composed of TreeViewItem's.

My tree is populated thru DataContext, from a class made by me, implementing the ObservableCollection.

The code provided, in this case doesnt work.

Does anyone has a clue why this happens and what i have to do in order to have this working on my custom made tree

Thx,

Nuno




Re: Windows Presentation Foundation (WPF) How to select an item in a TreeView, clicking in the right button?

Marlon Grech


Hi there,

the reason why Benny's code is not working is that Benny added treeviewitems to the treeview directly while you are setting the itemsource and passing a collection of objects that you defined.

When you add treeview items the treeview will push those tree view item objects in its Items collection while if you push your own object the treeview will push those objects in the items collection..

P.S this is since there is this method in the treeview control
protected override bool IsItemItsOwnContainerOverride(object item)
{
return item is TreeViewItem;
}

Any way... HOW TO FIX THIS

public Window1()
{
InitializeComponent();

treeview.ItemsSource = new string[]
{
"Hello",
"Hello",
"Hello",
"Hello",
"Hello"
};
this.Loaded += new RoutedEventHandler(Window1_Loaded);
}

void Window1_Loaded(object sender, RoutedEventArgs e)
{
//Attach Mouse Down handler
foreach (object item in treeview.Items)
{
TreeViewItem treeItem = treeview.ItemContainerGenerator.ContainerFromItem(item) as TreeViewItem;
AttachMouseDown(treeItem);
}
}

private void AttachMouseDown(TreeViewItem item)
{
item.MouseDown += new MouseButtonEventHandler(item_MouseDown);
if (item.Items.Count != 0)
{
foreach (object itemObj in item.Items)
{
TreeViewItem treeItem = treeview.ItemContainerGenerator.ContainerFromItem(itemObj) as TreeViewItem;
AttachMouseDown(treeItem);
}
}
}

void item_MouseDown(object sender, MouseButtonEventArgs e)
{
TreeViewItem item = sender as TreeViewItem;
if (e.RightButton == MouseButtonState.Pressed)
{
item.IsSelected = true;
MessageBox.Show(String.Format("{0} has been right clicked!", item.Header));
}
}

as you can see I am using Benny's code with the only difference that this code first gets the treeview item (ItemContainerGenerator.ContainerFromItem(itemObj))

I hope this helps... if not let us know Smile

REGARDS





Re: Windows Presentation Foundation (WPF) How to select an item in a TreeView, clicking in the right button?

lpx

Hi,

Sorry, i previously marked this as an answer but i havent looked at it until today.

It didnt worked.

I created a project with all the relevant information about this issue:

http://www.imaginando.net/~lpx/AnotherTreeViewTest.zip

The only problem is that the items are not being represented as in my original project, something wrong but i cant find what.

But everything is there and i will specify whats wrong when i found it. Maybe its something so simple that some of you will see it imediatly.

I hope you could help me out as i'm already saturated with this issue.

Many thx,

Best regards,

Nuno




Re: Windows Presentation Foundation (WPF) How to select an item in a TreeView, clicking in the right button?

Jeremy Chaney

I had the same problem. Here is the code you need (I'm also populating my tree via setting the ItemsSource property):

Code Snippet
public Object FindParentControlOfType(object childObject, Type type)

{
FrameworkElement childElement = childObject as FrameworkElement;
if ((childElement != null) && childElement.GetType() == type)
return childElement;

if (childElement == null)
return null;

FrameworkElement parentElement = VisualTreeHelper.GetParent(childElement) as FrameworkElement;

if (parentElement == null)
return null;

if (parentElement.GetType() == type)
return parentElement;

return FindParentControlOfType(parentElement, type);
}

public YourTreeViewClass()

{
InitializeComponent();
YourTreeViewClass.MouseRightButtonDown += new System.Windows.Input.MouseButtonEventHandler(YourTreeViewClass_MouseRightButtonDown);
}

void YourTreeViewClass_MouseRightButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
//on right click, select the item so that if someone chooses an operation from the context menu, we know which
//item to operate on.
TreeViewItem item = FindParentControlOfType(e.OriginalSource, typeof(TreeViewItem)) as TreeViewItem;
if (item != null)
{
item.IsSelected = true;
}
}






Re: Windows Presentation Foundation (WPF) How to select an item in a TreeView, clicking in the right button?

lpx

Hi,

My main problem as finally been solved! Thx a lot! That was messing my mind up.

But now i have another problem which is somekind related.

I want to expand a node and its children by the time its created (to avoid that boring thing of expanding them by and.

I have created an event handler for the collection changed event on my items source.

And the i was doing the following:
Code Snippet

void networkExplorer_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
foreach (object obj in e.NewItems)
{
TreeViewItem item = FindParentControlOfType(obj, typeof(TreeViewItem)) as TreeViewItem;
ExpandNodeAndItsChildren(item);
}
}


Where ExpandNodeAndItsChildren is:
Code Snippet

private void ExpandNodeAndItsChildren(TreeViewItem item)
{
item.IsExpanded = true;

foreach (TreeViewItem childItem in item.Items)
{
ExpandNodeAndItsChildren(childItem);
}
}



But i cant get the TreeViewItem.

I think i can understand why. When i'm clicking in a treeview, what i'm clicking is in a visual element, so that mut be translated into a TReeViewItem.

In this case i really have an item of my type and i want to get the TreeViewItem that contains it.

Well... can someone give me a tip here

Many thx,

Nuno







Re: Windows Presentation Foundation (WPF) How to select an item in a TreeView, clicking in the right button?

Jeremy Chaney

You need to add an observer for the ItemContainerGenerator:


Code Snippet


private void SomeMethodYouCallAfterPopulatingYourTree(TreeViewItem yourTreeViewItem)

{

if (yourTreeViewItem.ItemContainerGenerator.Status != System.Windows.Controls.Primitives.GeneratorStatus.ContainersGenerated)
{
// items aren't generated, let us know when they are
yourTreeViewItem.ItemContainerGenerator.StatusChanged += new EventHandler(ItemContainerGenerator_StatusChanged);
}
else
{
yourTreeViewItem.IsSelected = true;
}

}



void ItemContainerGenerator_StatusChanged(object sender, EventArgs e)
{
// a selection is pending, try to select the procedure
ItemContainerGenerator items = sender as ItemContainerGenerator;
if (items != null && items.Status == System.Windows.Controls.Primitives.GeneratorStatus.ContainersGenerated)
{
TreeViewItem tvi = items.ContainerFromIndex(0) as TreeViewItem;
if (tvi != null)
tvi.IsSelected = true;
}
}
}






Re: Windows Presentation Foundation (WPF) How to select an item in a TreeView, clicking in the right button?

Greg McPherran

There are ways of handling this so that can set IsSelected on TreeViewItem for right click.


Strategy 1: In the lowest VisualTree object (typically the application object of interest that the tree items are used for) you can add a reference to the TreeViewItem as a member. This would need to be done as you populate the tree. This associates the TreeViewItem with the object so that you don't need to search up the VisualTree.

Strategy 2: Search up the VisualTree for object of TreeViewItem type. This thread has example. Recursively use VisualTreeHelper to get Parent until TreeViewItem object found.

Strategy 3: This is the most elegant. Use a HierarchicalDataTemplate. Bind the Tag of lowest VisualTree object (typically the application object of interest that the tree items are used for) to RelativeSource with FindAncestor Mode and Ancestor Type of TreeViewItem. This works for sure as I have implemented it for app. Then when select item, it's Tag is the associated TreeViewItem. This is similar to Strategy 1 but the template does it automatically for you.