2

それは可能ですか?可能であれば、Silverlight(4)TreeViewコントロールに次の階層構造を実装するための最良の方法は何ですか?(ここで、ItemとGroupは、ツリーに存在できるクラスです)。


Group
|
|-Item
|
|-Group
| |
| |-Item
| |
| |-Item
|
|-Item

もちろん、必要に応じて、構造をこれよりも任意に複雑にすることもできます。

HierarchicalDataTemplatesはこれにアプローチする方法のように見えますが、さまざまなクラスを正しく解釈するためにテンプレートを適用する方法を理解するのに特に問題があります。

同様の質問がWPFについて尋ねられました。その答えは、HierarchicalDataTemplateのTargetTypeプロパティを利用しましたが、私の環境ではアクセスできないように見えるため、そのプロパティがSilverlightバージョンで使用できるかどうかはわかりません。

4

2 に答える 2

2

Silverlightの場合、これを行うためにコンバーターを作成する必要がある場合があります。たとえば、「ターゲットタイプデータテンプレートセレクター」などです。

より高度なものにすることもできますが、ハードコードされたタイプのデータテンプレートのインスタンスを提供できるSilverlight単体テストフレームワークの例を次に示します。一般化されたバージョンはおそらく約20分で作成できます。

これを使用するには、データテンプレートのインスタンスを提供しますが、この場合は、おそらくそれらを階層化する必要があります。

<local:DataTemplateSelector 
    x:Key="DetailsViewDataTemplate"
    DefaultDataTemplate="{StaticResource DefaultDataTemplate}"
    TestMethodTemplate="{StaticResource TestMethodDataTemplate}"
    TestClassTemplate="{StaticResource TestClassDataTemplate}"/>

そして、ここに実装があります:

/// <summary>
/// A specialized data template selector.
/// </summary>
public sealed class DataTemplateSelector : IValueConverter
{
    /// <summary>
    /// Gets or sets the default data template.
    /// </summary>
    public DataTemplate DefaultDataTemplate { get; set; }

    /// <summary>
    /// Gets or sets the test method template.
    /// </summary>
    public DataTemplate TestMethodTemplate { get; set; }

    /// <summary>
    /// Gets or sets the test class template.
    /// </summary>
    public DataTemplate TestClassTemplate { get; set; }

    /// <summary>
    /// Initializes a new instance of the DataTemplateSelector type.
    /// </summary>
    public DataTemplateSelector()
    {
    }

    /// <summary>
    /// Convert a value to a data template.
    /// </summary>
    /// <param name="value">The value.</param>
    /// <param name="targetType">The target parameter.</param>
    /// <param name="parameter">ConverterParameter value.</param>
    /// <param name="culture">The culture parameter.</param>
    /// <returns>Returns the object.</returns>
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value != null)
        {
            Type type = value.GetType();

            if (typeof(TestMethodData).TypeHandle == type.TypeHandle)
            {
                return TestMethodTemplate;
            }
            else if (typeof(TestClassData).TypeHandle == type.TypeHandle)
            {
                return TestClassTemplate;
            }
        }

        return DefaultDataTemplate;
    }

    /// <summary>
    /// No 2-way databinding support.
    /// </summary>
    /// <param name="value">The value.</param>
    /// <param name="targetType">The target parameter.</param>
    /// <param name="parameter">ConverterParameter value.</param>
    /// <param name="culture">The culture parameter.</param>
    /// <returns>Returns the object.</returns>
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return null;
    }
}
于 2010-03-22T19:21:41.410 に答える
1

私の実装

<UserControl.Resources>

    <DataTemplate x:Key="DefaultDataTemplate">
        <TextBlock Text="Default"/>
    </DataTemplate>

    <DataTemplate x:Key="ConditionDataTemplate">
        <Grid>
            <TextBlock Text="{Binding ConditionType}" Margin="5" Width="100"/>
        </Grid>
    </DataTemplate>

    <DataTemplate x:Key="ButtonDataTemplate">
        <Grid>
            <Button Content="{Binding Name}"/>
        </Grid>
    </DataTemplate>

    <DataTemplate x:Key="FieldDataTemplate">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition/>
                <ColumnDefinition/>
                <ColumnDefinition/>
            </Grid.ColumnDefinitions>
            <ComboBox Grid.Column="0" ItemsSource="{Binding Fields}" SelectedItem="{Binding Name,Mode=TwoWay}" Margin="5,0,5,0"/>
            <ComboBox Grid.Column="1" ItemsSource="{Binding ConditionTypes}" SelectedItem="{Binding ConditionType,Mode=TwoWay}" Margin="5,0,5,0"/>
            <TextBox Grid.Column="2" Text="{Binding Value, Mode=TwoWay}" Margin="5" Width="100"/>
        </Grid>
    </DataTemplate>

    <local:DataTemplateSelector 
            x:Key="DetailsViewDataTemplate"
            DefaultDataTemplate="{StaticResource DefaultDataTemplate}"
            ConditionDataTemplate="{StaticResource ConditionDataTemplate}"
            FieldDataTemplate="{StaticResource FieldDataTemplate}"
            ButtonDataTemplate="{StaticResource ButtonDataTemplate}"/>
</UserControl.Resources>
<Grid>
    <sdk:TreeView ItemsSource="{Binding Tree}">
        <sdk:TreeView.ItemTemplate>
            <sdk:HierarchicalDataTemplate ItemsSource="{Binding ChildNodes}">
                    <ContentControl ContentTemplate="{Binding Converter={StaticResource DetailsViewDataTemplate}}" Content="{Binding}"/>
            </sdk:HierarchicalDataTemplate>
        </sdk:TreeView.ItemTemplate>
    </sdk:TreeView>
</Grid>

MainClass

    public class MainPageModel : BaseModel
{
    private ObservableCollection<object> _Tree;
    public ObservableCollection<object> Tree
    {
        get
        {
            return _Tree;
        }
        set
        {
            _Tree = value;
            Notify("Tree");
        }
    }

    public MainPageModel()
    {
        Tree = new ObservableCollection<object>();
        Tree.Add(new Condition()
        {
            ConditionType = "OR",
                ChildNodes = new ObservableCollection<object>()
                {
                    new Field()
                        {
                            Name = "Поле 2", 
                            ConditionType = "=",
                            Value = "3"
                    },
                    new Field()
                        {
                            Name = "Поле 3",
                            ConditionType = ">",
                            Value = "3"
                    },
                    new Field()
                        {
                            Name = "Поле 4",
                            ConditionType = "<",
                            Value = "3"
                    },
                    new Condition() 
                    { 
                        ConditionType = "AND" ,
                    ChildNodes = new ObservableCollection<object>()
                    {
                        new Field()
                            {
                                Name = "Поле 2",
                                ConditionType = "=", 
                                Value = "3"
                            },
                        new Field()
                            {
                                Name = "Поле 3",
                                ConditionType = ">",
                                Value = "3"

                        },
                        new Field()
                            {
                                Name = "Поле 4",
                                ConditionType = "<",
                                Value = "3"
                        },
                        new Button()
                        {
                                Name = "Добавить"
                        }
                    }
                }
            }
            });
        Notify("Tree");
    }
}

public static class PickList
{
    public static ObservableCollection<string> Fields
    {
        get
        {
            return new ObservableCollection<string>() { "Поле 1", "Поле 2", "Поле 3", "Поле 4" };
        }
    }

    public static ObservableCollection<string> ConditionType
    {
        get
        {
            return new ObservableCollection<string>() { ">", "<", "=" };
        }
    }
}

public class Condition : BaseModel
{
    private ObservableCollection<object> _ChildNodes;
    public ObservableCollection<object> ChildNodes
    {
        get { return _ChildNodes; }
        set { _ChildNodes = value; Notify("ChildNodes"); }
    }

    public string ConditionType { get; set; }
}

public class Field : BaseModel
{
    public ObservableCollection<string> Fields
    {
        get
        {
            return PickList.Fields;
        }
    }
    public ObservableCollection<string> ConditionTypes
    {
        get
        {
            return PickList.ConditionType;
        }
    }

    public string Name { get; set; }
    public string ConditionType { get; set; }
    public string Value { get; set; }
}

public class Button : BaseModel
{
    public string Name { get; set; }
}

コンバータ

    public sealed class DataTemplateSelector : IValueConverter
{

    public DataTemplate ConditionDataTemplate { get; set; }

    public DataTemplate FieldDataTemplate { get; set; }

    public DataTemplate ButtonDataTemplate { get; set; }

    public DataTemplate DefaultDataTemplate { get; set; }

    public DataTemplateSelector()
    {
    }

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value != null)
        {
            Type type = value.GetType();


            if (typeof(Condition).TypeHandle == type.TypeHandle)
            {
                return ConditionDataTemplate;
            }
            else if (typeof(Field).TypeHandle == type.TypeHandle)
            {
                return FieldDataTemplate;
            }
            else if (typeof(Button).TypeHandle == type.TypeHandle)
            {
                return ButtonDataTemplate;
            }
        }

        return DefaultDataTemplate;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return null;
    }
}

フィールド表示タイプDateTime、Bool、...を追加する予定です。

于 2013-11-11T17:16:04.097 に答える