我有一个复杂的问题,我一直努力工作一周,现在正在努力工作。我正在使用WPF .NET 4.5,MVVM模式和Prism。我想显示绑定到ObservableCollection<IScript> LoadedScripts
:
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; }
...
}
}
我希望TreeView显示脚本列表和每个脚本,以便为脚本的部分创建子代。对于每个可见的节点,我想显示名称和状态。也就是说,IScript
中的每个LoadedScripts
都会显示ScriptDescription.Name
和ScriptDescription.Status
的文本框。对于每个子ISectionDescription
,包含ISectionDescription.Name
和ISectionDescription.Status
。
这一切都相当简单,除了我绑定到Interfaces的事实。我发现我应该能够使用DataTemplateSelector
来克服这个问题,但是我的树视图没有在我的模板中正确显示文本。相反,我在object.ToString()
中IScript
获得ObservableCollection<IScript> LoadedScripts
没有孩子的Output
。我也没有在DataTemplate
窗口中收到任何错误或警告。
我觉得我非常接近,但我无法正确显示我的数据。我已经确认我确实收到了我的数据,如果我为TreeView.ItemTemplate
添加基本IScript
,我就可以显示顶级namespace Library.App.GUI
{
public class ScriptDataTemplateSelector : DataTemplateSelector
{
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
FrameworkElement element = container as FrameworkElement;
if (element != null && item != null && item is IScript)
{
return element.FindResource("ScriptTemplate") as HierarchicalDataTemplate;
}
else if (element != null && item != null && item is ISectionDescription)
{
return element.FindResource("SectionTemplate") as DataTemplate;
}
return null;
}
}
}
节点。我不确定我做错了什么,非常感谢任何输入!
这是我的DataTemplateSelector:
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>();
}
}
}
ViewModel:
<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>
这是我的XAML:
{{1}}
P.S。:Library.Data命名空间中的所有内容我无法亲自编辑,因为它是一个外部库。如果必须发生,我可以提出改变请求,但不愿意。
P.P.S。:这是我的第一个问题,如果我遗漏了任何重要信息,请告诉我。谢谢!
答案 0 :(得分:2)
如果DataTemplateSelector
无效,您可能需要查看element.FindResource
是否返回任何内容。如果它返回null(或者您的as
返回null),则ToString
将用于显示树中的项目。