WPF C# Expand actual TreeNode invalid cast - c#

i have a TreeView which is binded trough a HierarchicalDataTemplate. Im listing there a List which contains a list of a directories and files.
private void getDirectoryList()
{
using (FileOperations fileOP = new FileOperations())
{
this.DokumentBrowser.ItemsSource = fileOP.list_directory(rpath); //Liste wird an den DokumentenBrowser gebunden
selectedOrdner = (Ordner)DokumentBrowser.Items.GetItemAt(0);
this.FileBrowser.DataContext = selectedOrdner.FileName;
}
}
The selectedOrdner buffers the Ordner Object which is actual selected by the user in the TreeView. If its empty it is set to the item at position 0 which is the root directory. When now the user puts a new file in the TreeView
runMethodtoCopyFile
getDirectoryList();
TreeViewItem tvi = (TreeViewItem)DokumentBrowser.ItemContainerGenerator.ContainerFromItem(DokumentBrowser.Items.CurrentItem);
tvi.IsExpanded = true;
tvi.Focus();
im runnning a method to copy the file and then im reading the new directory structure and want to set the expand property to true from the last treeviewitem which was selected. Because my TreeView was always showing me my rootnode when i put a new file or dir into it.
The Buffer of the selectedOrdner contains as long as im not putting a new file into it the Ordner Object. But when im running the method to copy a file it no longer contains an Object from type Ordner but treeviewitem instead.
I dont get it where it is changed from type Ordner to type TreeViewItem.
edit-----
The error always happens when the TreeView SelectedItemChanged happen.
private void DokumentBrowser_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
{
selectedOrdner = (Ordner)DokumentBrowser.SelectedItem;
FileBrowser.ItemsSource = selectedOrdner.FileName;
}
When I try to add something to the rootnode it works fine it only are the nodes after the first where it starts to break.
edit2------
There was a problem when binding the treeview to a new itemsource that the selecteditemchange method has a disconnecteditem and that could not be castet to a (Ordner)
solved this by making all changes over an observable collection. So the TreeViewItem is Expanded is not longer needed

Bring XAML to light please! ))
At the current state of inquiry it is hard to say something. May be problem in binding somewhere in your HierarchicalDataTemplate or it might be another piece of your codebehind.The only i can say now - you'd better check all your references from/to SelectedItem both in WPF XAML and C# code parts.
P.S.: Very strange by the way - usually people are confused with counterpart problem, how to get TreeViewItem for SelectedItem.

Related

Create a user definable WPF menu of favorite buttons/links/other controls

I am looking to have a user definable menu bar that contains a list of "favorite" actions that they can perform. I have a predefined menu of buttons which will perform different actions (open a new tab with content, update a record, etc.). I want the user to be able to select one of this controls, and choose to add it to their "favorite actions" which is a toolbar that will sit at the top of the page (this is currently done with a context menu). Ideally, the user will also be able to reorder this list of favorite actions.
Thus far, I've tried to use an ObservableCollection and List which is bound to a list view to tackle the first part of the problem. on the click method of the context menu, I have the following:
private void MenuItem_Click(object sender, RoutedEventArgs e)
{
MenuItem mnu = sender as MenuItem;
Button MyButton = null;
if (mnu != null)
{
ContextMenu MyContextMenu = (ContextMenu)mnu.Parent;
MyButton = MyContextMenu.PlacementTarget as Button;
}
dc.menuitems.Add(MyButton);
}
The list works when I add an object, however it did have issues firing INPC. When using an observable collection, I get the following error:
System.ArgumentException: 'Must disconnect specified child from current parent Visual before attaching to new parent Visual.'
I suspect this may be due to the fact that I'm somehow not creating a copy of the element, but rather reassigning it.
Is my approach the best approach? If so, how do I go about resolving the error that I see? What would be the best way to handle reordering of the items? I haven't been able to find much helpful information on creating such a control.
Once I've resolved this issue, I intend to use either a JSON or XML serializer to store this collection in the user settings to have their favorites stay persistent across application launches. Is this the best way to store this information?

connect object to listViewItem

I have an overview of some objects, displayed in a listView.
When an object is selected I want to show a form containing more details about the selected item.
public lessonForm(lesson foo)
[get and display data]
[...]
lessonListView.ItemActivate += lessonSelected;
void lessonSelected(object sender, eventArgs e)
{
lesson ??? = //REQUESTION MAGIC here.
new lessonForm(???).Show();
}
Since ListViewItems are acutally just texts and not programmatically connected to the lesson-object I used to create them, I have not found a proper way to find the respective lesson-object for each listViewItem.
Sure I could do
lesson ??? = Program.listOfAllLessons.Find((candidate) => {
return candidate.plainTextName == selectedItem.Text //abbrev. on purpose
});
However I think it is undisputed that that is just horrible code, on more than one level.
Basically:
I would wish for listViewItem to have an
obj underlyingObject;
field that allows for easy access to the object represented by the listViewItem.
Is there a functionality that allows for this?
You could use the Tag property to store the associated object when creating the ListViewItem. As Tag is of type object you'd need to cast it appropriately when you read from it.

Get the Selected Tree View Item

I am using a wpf tree in a .net form. So, I don't have any xaml. I simply do everything in code. I am using Hierarchical Data Template to bind my data to the wpftree.
I am trying to find a way to get the TreeViewItem for the Node selected in the tree. I tried registering a EventHandler on the SelectedItemChanged event on the TreeView, but in that handler I only get the associated data object. Since my tree is virtual, ItemContainerGenerator.ContainerFromItem doesn't work.
When I searched on StackOverflow, one suggestion was to listen to the TreeViewItem.Selected event.
But I couldn't find a way to do this in code. ( I don't have a xaml).
Any help is greatly appreciated.
thank you.
What you could do is attach the handler to each control every time you add it
void AddTreeViewItem()
{
TreeView t = new TreeView();
TreeViewItem treeItem = new TreeViewItem();
t.Items.Add(treeItem);
treeItem.Selected += DoSomethingHere;
}
private void DoSomethingHere(object sender, RoutedEventArgs e)
{
Console.WriteLine("Tree Item Selected");
}

How to add to a TreeView directory at runtime

I have a TreeView in which I would like to allow the user to add and delete subitems from. In exploring basic functionality I am using a button and a textbox to add this subitem. When the user clicks on the button a new TreeViewItem needs to be created and set as a subitem of my parent TreeView with the text from the textbox set as the subitem's Header.
This is my current code under the button_click event:
//ADD T_ITEM TO PARENT TREEVIEW
private void button1_Click(object sender, RoutedEventArgs e)
{
TreeViewItem item = new TreeViewItem();
item.Header = textBox1.Text;
//Compiler does not recognize "Nodes"
Parent.Nodes.Add(item);
}
Specifically, the compiler has a problem with Nodes. The main question that I've used to help me makes a lot of sense, but just doesn't work for me. All of the sources I have looked at uses the Nodes command at one time or another with no problem. Do I need to include a reference, or is my code completely off?
--This guide uses System.Windows.Forms; in order to use Nodes, but doesn't seem to help because I am using Windows Presentation Foundation.
Please show me how to get my code working in the right direction.
Thank you.
I did some more research and found the equivalent method for adding child TreeViewItems to parent TreeViewItems in WPF.
This is the change I made to my code:
//ADD T_ITEM TO PARENT TREEVIEW
private void button1_Click(object sender, RoutedEventArgs e)
{
TreeViewItem item = new TreeViewItem();
item.Header = textBox1.Text;
Parent.Items.Add(item);
}

Selecting a TreeView Item without invoking SelectedItemChanged?

In my app, I have a group of 3d objects and they're exposed to the user through a TreeView. When a user selects an item in the TreeView, an SelectedItemChanged event is fired, the corresponding 3d object is set to be selected and is highlighted in the 3d render window. This works fine.
What I'm having trouble with is the reverse. In a section of my code, I programatically set the selected 3d object in the scene. I want to reflect the currently selected object in the TreeView, so I run through the items until I find the corresponding one. But once I get to it, I can't find a way to make the item appear selected without having SelectedItemChanged being called, which is not what I want.
Is there a way to do this?
Thanks!
I take it you want to suppress the code in your event-handler? If so, a common way of doing this is with a boolean flag (or sometimes an int counter):
bool updatingSelected;
void SomeHandler(object sender, EventArgs args) { // or whatever
if(updatingSelected) return;
//...
}
void SomeCode() {
bool oldFlag = updatingSelected;
updatingSelected = true;
try {
// update the selected item
} finally {
updatingSelected = oldFlag;
}
}
Would it be appropriate to remove the TreeView's SelectedItemChanged event handler temporarily, and re-add it once you've performed the necessary operations? I haven't tried it myself, but it's the only other thing I can think of (Marc Gravell beat me to my original answer - I've done THAT before ;) ).
Good luck!

Categories