C# 将TreeView绑定到HierarchycalDataTemplate和DataTemplate,其中DataType是接口

C# 将TreeView绑定到HierarchycalDataTemplate和DataTemplate,其中DataType是接口,c#,wpf,interface,treeview,hierarchicaldatatemplate,C#,Wpf,Interface,Treeview,Hierarchicaldatatemplate,我有一个复杂的问题,这一周我一直在努力解决,现在我正在努力正确地工作。我正在使用WPF.NET4.5、MVVM模式和Prism。我想显示一个树状视图,该视图绑定到加载脚本的可观察收集: namespace Library.Data.Scripting { public interface IScript : INotifyPropertyChanged { ... IScriptDescription ScriptDescription

我有一个复杂的问题,这一周我一直在努力解决,现在我正在努力正确地工作。我正在使用WPF.NET4.5、MVVM模式和Prism。我想显示一个树状视图,该视图绑定到加载脚本的
可观察收集:

namespace Library.Data.Scripting    
{
    public interface IScript : INotifyPropertyChanged
    {
        ...

        IScriptDescription ScriptDescription { get; }

        ...
    }


    public interface IScriptDescription : INotifyPropertyChanged
    {
        ...

        string Name { get; }
        IEnumerable<ISectionDescription> Sections { get; }
        ScriptStatus Status { get; }

        ...
    }

    public interface ISectionDescription : INotifyPropertyChanged
    {
        ...

        string Name { get; }
        ScriptStatus Status { get; }

        ...
    }
}
ViewModel:

namespace Library.App.GUI
{
    public class TestStatusViewModel
    {
        private IScriptManager ScriptManager;

        public ObservableCollection<IScript> LoadedScripts
        {
            get 
            { 
                return ScriptManager.LoadedScripts; 
            }
        }

        public TestStatusViewModel()
        {
            //Locate the ScriptManager in the MEF container using Microsoft.Practices.ServiceLocation.ServiceLocator
            ScriptManager = ServiceLocator.Current.GetInstance<IScriptManager>();
        }
    }
}
namespace Library.App.GUI
{
公共类TestStatusViewModel
{
私有IScriptManager脚本管理器;
公共ObservableCollection加载的脚本
{
得到
{ 
返回ScriptManager.LoadedScripts;
}
}
公共TestStatusViewModel()
{
//使用Microsoft.Practices.ServiceLocation.ServiceLocator在MEF容器中找到ScriptManager
ScriptManager=ServiceLocator.Current.GetInstance();
}
}
}
这是我的XAML:

<UserControl x:Class="Library.App.GUI.TestStatusView"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
            xmlns:local="clr-namespace:Library.App.GUI"
            xmlns:script="clr-namespace:Library.Data.Scripting;assembly=MTFCommon"
            xmlns:prism="clr-namespace:Microsoft.Practices.Prism;assembly=Microsoft.Practices.Prism"
            xmlns:sys="clr-namespace:System;assembly=mscorlib"
            mc:Ignorable="d" 
            d:DesignHeight="600" d:DesignWidth="200">


    <UserControl.Resources>
        <local:ScriptDataTemplateSelector x:Key="ScriptTemplateSelector"/>

        <HierarchicalDataTemplate  x:Key="ScriptTemplate" ItemsSource="{Binding ScriptDescription.Sections}">
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto"/>
                    <ColumnDefinition />
                </Grid.ColumnDefinitions>

                <TextBlock Grid.Column="0" TextAlignment="Left" Text="{Binding ScriptDescription.Name}" />
                <TextBlock Grid.Column="1" TextAlignment="Right" FontWeight="Bold" HorizontalAlignment="Stretch" Text="{Binding ScriptDescription.Status}" />
            </Grid>
        </HierarchicalDataTemplate>

        <DataTemplate x:Key="SectionTemplate">
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto"/>
                    <ColumnDefinition />
                </Grid.ColumnDefinitions>

                <TextBlock Grid.Column="0" TextAlignment="Left" Text="{Binding Name}" />
                <TextBlock Grid.Column="1" TextAlignment="Right" FontWeight="Bold" HorizontalAlignment="Stretch" Text="{Binding Status}" />
            </Grid>
        </DataTemplate>
    </UserControl.Resources>

    <ItemsControl HorizontalAlignment="Stretch">
            <TreeView Name="treeView" ItemTemplateSelector="{StaticResource ScriptTemplateSelector}" ItemsSource="{Binding LoadedScripts}" />
    </ItemsControl>

</UserControl>

附言:库中的所有内容。数据命名空间我个人无法编辑,因为它是一个外部库。如果有必要的话,我可以提出更改的请求,但我不愿意


这是我的第一个问题,如果我遗漏了任何重要信息,请告诉我。谢谢

如果您的
DataTemplateSelector
不工作,您可能需要检查
元素.FindResource
是否返回任何内容。如果它返回null(或者你的
as
返回null),那么
ToString
将用于显示树中的项目。

我已经在我的
DataTemplateSelector
中设置了断点,并查看它触发集合中
IScript
的正确次数,它返回一个
DataTemplate
对象。然而,它的行为似乎并没有实际使用返回的
DataTemplate
。它就像一个冠军。您正在运行哪个版本的.NET?我在VS2012中使用我的所有可用目标进行了测试(我安装了4.5和所有service Pack)。您的输出窗口中是否有任何绑定错误?我正在运行.NET 4.5 VS2012。我刚刚意识到我确实也得到了孩子们,但仍然只是
Library.Script
Library.SectionDescription
而不是实际的数据。我想我可能在绑定或其他方面有问题。尽管如此,如果我将文本静态设置为“foobar”的文本框中,仍然会得到相同的结果。shrugSo,设置
文本框。Text=“foobar”
将在输出中显示类型名称?您可能希望创建一个简单的示例应用程序,以确保您没有在某处设置
ItemTemplate
ItemTemplateSelector
。我正在将我的
TreeView
中的
ItemTemplateSelector
设置为我定义的
DataTemplateSelector
<UserControl x:Class="Library.App.GUI.TestStatusView"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
            xmlns:local="clr-namespace:Library.App.GUI"
            xmlns:script="clr-namespace:Library.Data.Scripting;assembly=MTFCommon"
            xmlns:prism="clr-namespace:Microsoft.Practices.Prism;assembly=Microsoft.Practices.Prism"
            xmlns:sys="clr-namespace:System;assembly=mscorlib"
            mc:Ignorable="d" 
            d:DesignHeight="600" d:DesignWidth="200">


    <UserControl.Resources>
        <local:ScriptDataTemplateSelector x:Key="ScriptTemplateSelector"/>

        <HierarchicalDataTemplate  x:Key="ScriptTemplate" ItemsSource="{Binding ScriptDescription.Sections}">
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto"/>
                    <ColumnDefinition />
                </Grid.ColumnDefinitions>

                <TextBlock Grid.Column="0" TextAlignment="Left" Text="{Binding ScriptDescription.Name}" />
                <TextBlock Grid.Column="1" TextAlignment="Right" FontWeight="Bold" HorizontalAlignment="Stretch" Text="{Binding ScriptDescription.Status}" />
            </Grid>
        </HierarchicalDataTemplate>

        <DataTemplate x:Key="SectionTemplate">
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto"/>
                    <ColumnDefinition />
                </Grid.ColumnDefinitions>

                <TextBlock Grid.Column="0" TextAlignment="Left" Text="{Binding Name}" />
                <TextBlock Grid.Column="1" TextAlignment="Right" FontWeight="Bold" HorizontalAlignment="Stretch" Text="{Binding Status}" />
            </Grid>
        </DataTemplate>
    </UserControl.Resources>

    <ItemsControl HorizontalAlignment="Stretch">
            <TreeView Name="treeView" ItemTemplateSelector="{StaticResource ScriptTemplateSelector}" ItemsSource="{Binding LoadedScripts}" />
    </ItemsControl>

</UserControl>