public static void SetXmlItemSelected(ref TreeView container, XmlNode node)
{
if (container.HasItems)
{
//cast to xml-nodes
var xmlNodeList = container.Items.Cast<XmlNode>(); ;
//node at root level? -> select it
if (xmlNodeList.Contains(node))
{
(container.ItemContainerGenerator.ContainerFromItem(node) as TreeViewItem).IsSelected = true;
}
else
{
//get rootnode
XmlNode rootNode = GetRootNode(node, xmlNodeList);
//get a list of parent nodes
List<XmlNode> parentNodes = new List<XmlNode>();
GetAllParentNodes(rootNode, node, ref parentNodes);
parentNodes.Reverse();
//finaly, select the node
SelectNode(parentNodes, node, ref container, null);
}
}
}
private static XmlNode GetRootNode(XmlNode node, IEnumerable<XmlNode> xmlNodeList)
{
if (!xmlNodeList.Contains(node) && node.ParentNode != null)
{
return GetRootNode(node.ParentNode, xmlNodeList);
}
else if (xmlNodeList.Contains(node)) return node;
else return null;
}
private static void GetAllParentNodes(XmlNode rootNode, XmlNode actualNode, ref List<XmlNode> parentNodes)
{
if (actualNode.ParentNode != null && !actualNode.Equals(rootNode))
{
parentNodes.Add(actualNode.ParentNode);
GetAllParentNodes(rootNode, actualNode.ParentNode, ref parentNodes);
}
}
private static void SelectNode(List<XmlNode> parentNodes, XmlNode node, ref TreeView container, [Optional, DefaultParameterValue(null)] TreeViewItem item)
{
if (parentNodes.Count > 0)
{
TreeViewItem tvItem;
if (item != null)
tvItem = item.ItemContainerGenerator.ContainerFromItem(parentNodes.First()) as TreeViewItem;
else
tvItem = container.ItemContainerGenerator.ContainerFromItem(parentNodes.First()) as TreeViewItem;
parentNodes.RemoveAt(0);
SelectNode(parentNodes, node, ref container, tvItem);
}
else if (item != null)
{
(item.ItemContainerGenerator.ContainerFromItem(node) as TreeViewItem).IsSelected = true;
}
}
|
|
|
Vielleicht postest Du mal den Link auf die Quelle für Dein Code-Beispiel, und zum Vergleich den Code, der Deinen TreeView befüllt.
– Matthias Hlawatsch 03.01.2012
|
<TreeView Name="trvTreeViewMain" SelectedItemChanged="trvTreeViewMain_SelectedItemChanged">
<TreeViewItem ItemsSource="{Binding Source={StaticResource RootData}, XPath=*}" Header="Rezeptgruppen" IsExpanded="True" ContextMenu="{StaticResource GroupContextMenu}"/>
</TreeView>
// als container muss dann das erste TreeViewItem aus dem TreeView übergeben werden
public static void SetXmlItemSelected(ref TreeViewItem container, XmlNode node)
{
if (container.HasItems)
{
//cast to xml-nodes
var xmlNodeList = container.Items.Cast<XmlNode>();
...
|
|
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE Root [
<!ELEMENT Root ANY>
<!ELEMENT Node ANY>
<!ATTLIST Node Id ID #REQUIRED>
<!ATTLIST Node ParentID CDATA #REQUIRED >
<!ATTLIST Node Header CDATA #REQUIRED>
]>
<Root>
</Root>
<Window x:Class="WpfApplication1.XmlTreeviewDemo"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:jsCtr="clr-namespace:js.WPFbase.Controls;assembly=jsWPFbase"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
Title="XmlTreeviewDemo" Height="434" Width="408">
<Window.Resources>
<XmlDataProvider x:Key="RootData" XPath="/Root"/>
<HierarchicalDataTemplate DataType="Node" ItemsSource="{Binding}">
<TextBlock Text="{Binding XPath=@Header}" />
</HierarchicalDataTemplate>
<ContextMenu x:Key="GroupContextMenu">
<MenuItem Header="Neue Hauptgruppe" Command="New"/
<MenuItem Header="Grupppe anfügen" Command="Open"/>
</ContextMenu>
</Window.Resources>
<Grid>
<TreeView Name="trvTreeViewMain" SelectedItemChanged="trvTreeViewMain_SelectedItemChanged">
<TreeViewItem ItemsSource="{Binding Source={StaticResource RootData}, XPath=*}" Header="Rezeptgruppen" IsExpanded="True" ContextMenu="{StaticResource GroupContextMenu}"/>
</TreeView>
</Grid>
</Window>
public class GroupItem : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private string _header;
private int _id;
private int _parentID;
public GroupItem(string header, int id, int parentID)
{
Header = header;
Id = id;
ParentID = parentID;
}
public string Header
{
get { return _header; }
set
{
_header = value;
Changed("Header");
}
}
public int Id
{
get { return _id; }
set
{
_id = value;
Changed("Id");
}
}
public int ParentID
{
get { return _parentID; }
set
{
_parentID = value;
Changed("ParentID");
}
}
public override string ToString()
{
return Header;
}
private void Changed(string propertyName)
{
if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
public class XmlDoc : XmlDocument
{
public XmlDocument GetDocument { get { return this; } }
private XmlElement _rootElement = null;
private int _treeViewIndex = 0;
public XmlDoc(string path)
{
try
{
this.Load(path);
_rootElement = this.DocumentElement;
}
catch (Exception e) { throw e; }
}
public void AddElement(XmlElement element, int parentID)
{
if (parentID < 1)
{
_rootElement.AppendChild(element);
}
else
{
XmlElement el = this.GetElementById(IdToString(parentID));
el.AppendChild(element);
}
}
public string IdToString(int id)
{
return "_" + id.ToString();
}
public int IdToInt(string id)
{
return int.Parse(id.Substring(1));
}
public int GetTreeViewIndex
{
get
{
_treeViewIndex++;
return _treeViewIndex;
}
}
}
public partial class XmlTreeviewDemo : Window
{
private ObservableCollection<GroupItem> _dataCollection;
private XmlDataProvider _dataProvider = null;
private XmlDoc _document = null;
private int _newID = 15;
public XmlTreeviewDemo()
{
CommandBindings.Add(new CommandBinding(ApplicationCommands.New, AddNewGroup));
CommandBindings.Add(new CommandBinding(ApplicationCommands.Open, AddNewGroup));
_dataProvider = (XmlDataProvider)trvMain.FindResource("RootData");
AddData();
AddDocument();
}
private void AddData()
{
_dataCollection.Add(new GroupItem("Fleisch", 1, -1));
_dataCollection.Add(new GroupItem("Rind", 2, 1));
_dataCollection.Add(new GroupItem("Kalb", 3, 1));
_dataCollection.Add(new GroupItem("Schwein", 4, 1));
_dataCollection.Add(new GroupItem("Geflügel", 5, 1));
_dataCollection.Add(new GroupItem("Huhn", 6, 5));
_dataCollection.Add(new GroupItem("Beilagen", 7, -1));
_dataCollection.Add(new GroupItem("Kartoffel", 8, 7));
_dataCollection.Add(new GroupItem("Teigwaren", 9, 7));
_dataCollection.Add(new GroupItem("Teigspeisen", 10, 7));
_dataCollection.Add(new GroupItem("Niocci", 11, 10));
_dataCollection.Add(new GroupItem("Brust", 12, 6));
_dataCollection.Add(new GroupItem("Schnitzel", 13, 12));
_dataCollection.Add(new GroupItem("Geschnetzeltes", 14, 12));
}
private void AddDocument()
{
_document = new XmlDoc("MyPtah");
foreach (cit.GroupItem item in _dataCollection)
{
if (item.ParentID == -1)
{
_document.AddElement(CreateNewElement(item), -1);
}
else
{
_document.AddElement(CreateNewElement(item), item.ParentID);
}
}
_dataProvider.Document = _document.GetDocument;
}
private XmlElement CreateNewElement(GroupItem item)
{
XmlAttribute atId = _document.CreateAttribute("Id");
atId.Value = _document.IdToString(item.Id);
XmlAttribute atPId = _document.CreateAttribute("ParentID");
atPId.Value = item.ParentID.ToString();
XmlAttribute atHeader = _document.CreateAttribute("Header");
atHeader.Value = item.Header;
XmlElement el = _document.CreateElement("Node");
el.Attributes.Append(atId);
el.Attributes.Append(atPId);
el.Attributes.Append(atHeader);
return el;
}
private void AddNewGroup()
{
GroupItem item = new GroupItem("Irgendwas", _newID, -1);
_newID++;
_document.AddElement(CreateNewElement(item),-1);
SetElementSelected(item);
}
private void AddGroup()
{
int parentID = _document.IdToInt(GetSelectedItem().Attributes["Id"].Value);
GroupItem item = new GroupItem("Irgendwas", _newID, parentID);
_newID++;
_document.AddElement(CreateNewElement(item), -parentID);
//Da hier im TreeView das Element nicht angezeigt wird, den TreeView neu laden
AddDocument();
SetElementSelected(item);
}
private XmlNode GetSelectedItem()
{
try
{
return (XmlNode)trvMain.SelectedItem;
}
catch { return null; }
}
private void SetElementSelected(GroupItem item)
{
XmlNode nd = _document.GetElementById(_document.IdToString(item.Id));
//Hier kommt der Aufruf zu der Function, siehe Link
}
}
|
|
|
Bitte verschiebe diesen Post in Deine Frage (per Edit-Funktion). Antworten sind hier für Antworten auf die ursprüngliche Frage gedacht, nicht für Antworten auf Rückfragen in Kommentaren.
Im übrigen scheint der Code nicht ganz konsistent zu sein: im XAML heißt es trvTreeViewMain, im Code-Behind aber trvMain. – Matthias Hlawatsch 04.01.2012
|