1

1 週間にわたって取り組んできた複雑な質問があり、正しく機能するようになりました。私は WPF .NET 4.5、MVVM パターン、および Prism を使用しています。にバインドする TreeView を表示したい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のテキスト ボックスが表示されます。子ごとに、とを含む TextBox 。ScriptDescription.NameScriptDescription.StatusISectionDescriptionISectionDescription.NameISectionDescription.Status

インターフェイスにバインドしていることを除けば、これはすべて非常に簡単です。を使用してこれを克服できるはずの方法を見つけましたDataTemplateSelectorが、ツリービューでテンプレートにテキストが正しく表示されません。代わりに、私は子供のいない私object.ToString()IScripts を取得しています。ウィンドウObservableCollection<IScript> LoadedScriptsにエラーや警告も表示されません。Output

本当に近い気がしますが、データを正しく表示できません。私は実際にデータを取得していることを確認しました.basic DataTemplateforTreeView.ItemTemplateを配置すると、トップレベルのIScriptノードを表示できます。何が間違っているのかわかりません。どんな意見でも大歓迎です!

ここに私の DataTemplateSelector があります:

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;
        }

    }
}

ビューモデル:

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>();
        }
    }
}

ここに私の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>

PS: Library.Data 名前空間のすべては、外部ライブラリであるため、個人的に編集することはできません。変更が必要な場合は、変更をリクエストできますが、希望しません。

PPS: これは私の最初の SO の質問です。重要な情報を見逃していた場合はお知らせください。ありがとう!

4

1 に答える 1