Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
c#XML树视图(管道)_C#_Xml_Xaml_Treeview_Tree Nodes - Fatal编程技术网

c#XML树视图(管道)

c#XML树视图(管道),c#,xml,xaml,treeview,tree-nodes,C#,Xml,Xaml,Treeview,Tree Nodes,我正在创建一个XML查看器,它应该能够读取每个XML文件并将其放在树视图中。 我的目标是创建一个XMLViewer控件,用户应该能够在自己的实现中更改某些例程。我提供了提供基本功能的默认实现,以便XML查看器至少显示默认行为。我正试图通过管道和代理来实现这一点 到目前为止我拥有的: MainWindow.xaml <Grid> <Grid.RowDefinitions> <RowDefinition Height="30*" />

我正在创建一个XML查看器,它应该能够读取每个XML文件并将其放在树视图中。 我的目标是创建一个XMLViewer控件,用户应该能够在自己的实现中更改某些例程。我提供了提供基本功能的默认实现,以便XML查看器至少显示默认行为。我正试图通过管道和代理来实现这一点

到目前为止我拥有的:

MainWindow.xaml

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="30*" />
        <RowDefinition Height="25*" />
        <RowDefinition Height="175*" />
    </Grid.RowDefinitions>
    <StackPanel Grid.Row="0" Orientation="Horizontal" Margin="0,5,0,5">
        <TextBlock Text="XML File" VerticalAlignment="Center" />
        <TextBox Name="txtPath" Width="400" IsReadOnly="True" Margin="5,0,5,0"/>
        <Button Content="Open" Name="btnOpen"  />
    </StackPanel>

    <Button Name="btnPlumb" Content="Plumb the code!" Grid.Row="1"/>
    <uc:XMLTreeView x:Name="XMLOutput" Grid.Row="2" />
</Grid>
类XMLTreeView

namespace XMLViewer
{
class XMLTreeView : TreeView
{
    public XmlDocument doc;

    public void processXML(string path)
    {
        XmlDocument document = new XmlDocument();
        this.doc = document;
        doc.Load(path);

        foreach (XmlNode node in doc.ChildNodes)
        {
            XMLTreeViewItem newItem = new XMLTreeViewItem(node);
            this.AddChild(newItem);
        }
    }

    public void PlumbTheCode()
    {
        this.Items.Clear();

        foreach (XmlNode node in doc.ChildNodes)
        {
            XMLTreeViewItem newItem;
            newItem = new XMLTreeViewItem(node);

            newItem._LoadColor = new LoadColorDelegate(newItem.LoadColorPlumbed);
            newItem._LoadColor.Invoke(node);


            this.AddChild(newItem);
        }



    }
}
}
类XMLTreeViewItem

namespace XMLViewer
{

public delegate void LoadHeaderDelegate(XmlNode node);
public delegate void LoadColorDelegate(XmlNode node);
public delegate void CheckForChildrenDelegate(XmlNode node);

public class XMLTreeViewItem:TreeViewItem
{

   public LoadHeaderDelegate _LoadHeader { get; set; }
   public LoadColorDelegate _LoadColor { get; set; }
   public CheckForChildrenDelegate _CheckForChildren { get; set; }

    public XMLTreeViewItem(XmlNode node)
    {
        _LoadHeader = new LoadHeaderDelegate(LoadHeader);
        _LoadColor = new LoadColorDelegate(LoadColor);
        _CheckForChildren = new CheckForChildrenDelegate(CheckForChildren);

        _LoadHeader.Invoke(node);
        _LoadColor.Invoke(node);
        _CheckForChildren.Invoke(node);
    }

    #region HEADER
    private void LoadHeader(XmlNode RootNode)
    {
        if (RootNode.HasChildNodes == false)
        {
            this.Header = RootNode.InnerText.ToUpper();
        }
        else
        {
            this.Header = RootNode.Name.ToUpper();
        }

        if (RootNode.Attributes != null)
        {
            foreach (XmlAttribute attr in RootNode.Attributes)
            {
                this.Header += " " + attr.Name + " = " + attr.InnerText;
            }
        }
    } 
    #endregion

    #region COLOR
    private void LoadColor(XmlNode node)
    {
        this.Foreground = Brushes.Black;
    }
    public void LoadColorPlumbed(XmlNode node)
    {
        this.Foreground = Brushes.Green;
    } 
    #endregion

    #region CHILDREN
    private void CheckForChildren(XmlNode node)
    {
        if (node.HasChildNodes)
        {
            LoadChildren(node);
        }
    }

    private void LoadChildren(XmlNode RootNode)
    {
        foreach (XmlNode node in RootNode.ChildNodes)
        {
            XMLTreeViewItem newItem = new XMLTreeViewItem(node);
            this.AddChild(newItem);
        }
    } 
    #endregion
}
}

我的目标:


正如你所看到的,我很难正确显示我的树节点。有人有办法解决这个问题吗?

好的,那么您正在尝试实现一个具有扩展点的树视图, 为xml节点定制颜色/标题

为此,您为每个XMLTreeViewItem添加了几个公共委托,该委托是哪个调用方 可以覆盖以提供自己的颜色/标题/等

当前解决方案的问题是,只有根节点才能获得用于着色的自定义委托。 构造根xml节点时,通过构造新的XMLTreeViewItem加载所有子节点,该项具有LoadColor委托的默认实现

您需要将代理替代复制到每个新创建的节点中,或者保留对已替代代理的根节点的引用

另一个问题是,整个XMLTreeViewItem树是在构造函数中生成的,并且委托重写仅在之后提供:

newItem = new XMLTreeViewItem(node);

newItem._LoadColor = new LoadColorDelegate(newItem.LoadColorPlumbed);
newItem._LoadColor.Invoke(node);
这意味着在您执行_LoadColor.Invoke时,整个树已经被构造并初始化了它的颜色_LoadColor=new LoadColorDelegate将覆盖您传递给所有子节点的委托,_LoadColor.Invoke将仅为根节点着色

我建议如何解决此问题:

将LoadHeader/CheckForChildren/LoadColor方法(您希望允许覆盖该方法)移动到XMLTreeView类,并在其中作为公共属性公开:

private void LoadColor(XMLTreeViewItem item, XmlNode node)
{
    item.Foreground = Brushes.Black;
}
修改XMLTreeViewItem的构造函数以接受的实例 XMLTreeView,并在每个节点中存储父引用:

public XMLTreeViewItem(XmlNode node, XMLTreeView parentTreeView)
{...}
现在,像这样构造树:

public void PlumbTheCode()
{
    this.Items.Clear();

    this._LoadColor = new LoadColorDelegate(newItem.LoadColorPlumbed);
    foreach (XmlNode node in doc.ChildNodes)
    {
        this.AddChild(new XMLTreeViewItem(node, this));
    }
}

另一种解决方案是将新的着色/头委托直接传递到XMLTreeItem构造函数中,并递归地传递到所有较低的节点中。这将保持XMLTreeView没有着色委托,但可能会使此类用户的自定义变得复杂,因为他们需要覆盖每个节点中的委托。

如果我理解您的意思是正确的,您需要数据的MasterDetails视图(即,您需要每个项目上的一些行)。我目前正在开发类似的东西,但是被所选项目的儿童表示所困扰。也许我的问题对你有帮助:
public void PlumbTheCode()
{
    this.Items.Clear();

    this._LoadColor = new LoadColorDelegate(newItem.LoadColorPlumbed);
    foreach (XmlNode node in doc.ChildNodes)
    {
        this.AddChild(new XMLTreeViewItem(node, this));
    }
}