I have a databound tree with two custom object types (containers and orders)
I made a prototype app that reproduces my issue. The issue seems to be fixed in 4.5 but I can not move my app from 3.5 just yet so I'm stuck looking for a solution.
When I move containers around in the tree the parent child relationships of the TreeViewItems are not maintained correctly.
I found this issue in my style selector. When the StyleSelector is called, I walk up the visual tree to get the UserControl(OrdersTreeView) then I inspect a property on that class to help determine which style to select.
There are alternative ways I can accomplish getting this property, but the fact that the parent child relationship is no longer accurate causes problems all over the application. In short, if I hack in a fix for getting the "editingEnabled"
property, I'm still going to have many other issues because the relationship is inaccurate.
public class TreeViewItemContainerStyleSelector : StyleSelector
{
public Style FolderEditableStyle { get; set; }
public Style FolderNotEditableStyle { get; set; }
public Style OrderEditableStyle { get; set; }
public Style OrderNotEditableStyle { get; set; }
public override Style SelectStyle(object item, DependencyObject container)
{
FrameworkElement element = container as FrameworkElement;
bool isPurchaseOrder = element.DataContext.GetType() == typeof(PurchaseOrder);
DependencyObject source = container;
while (source != null && !(source is OrdersTreeView))
source = VisualTreeHelper.GetParent(source);
bool editingEnabled = (source as OrdersTreeView).editingEnabled;
if (editingEnabled)
{
if (isPurchaseOrder)
{
return OrderEditableStyle;
}
else
{
return FolderEditableStyle;
}
}
else
if (isPurchaseOrder)
{
return OrderNotEditableStyle;
}
else
{
return FolderNotEditableStyle;
}
}
}
Below is a detailed description of my issue.
-root
-container1
-container1.1
-container1.2
-container2
-container2.2
Firstly, I have an ObservableCollection<object> as the tree's item source.
I've got drag and drop functionality coded up, and when I drag container1.1 to root it moves successfully. below is a snippet of the code to move the objects.
public void ucOrdersTreeView_editContainer(int containerID, int parentContainerID)
{
...
...
...
if (containerToMove.parentID != newParent.ID)
{
currentParent.children.Remove(containerToMove);
newParent.children.Add(containerToMove);
}
}
If you refer to the first snippet, the StyleSelector code functions correctly during this move, it walks the tree and chooses the correct style.
Now the tree is in this state, with container1.1 as a child of root.
-root
-container1
-container1.2
-container2
-container2.1
-container1.1
My issue now arises if I try to add any object as a child of the container I just moved. If i drag container1.2 into container 1.1 or I try to add a new container to container1.1 I see the issue.
The issue is that if I inspect the TreeViewItem for container1.1, it's VisualTreeHelper.GetParent("container1.1") returns null.
As I stated above, this issue seems to be resolved in .NET4.5. Is there a work around I can use to get the visual tree in the correct state without rebinding the TreeView to my ObservableCollection?
Thanks,
Zach
I have a small sample application that reproduces this issue but I could not find a simple way to attach the zip file to this form. I can send it on request.
Zach Steffens