使用自定义列表对象填充树视图

时间:2017-01-25 14:58:10

标签: c# wpf treeview

我有一个由2个属性组成的自定义对象。第一个是我希望在树视图中用作摘要或标题的字符串。第二个是自定义类型的列表,其中包含要包含在每个标题下的对象。对象包含诸如name,id,area等之类的东西.Ill很可能默认为那些列表对象的name属性。如何将其推入树视图中。 连锁模型

    public class WVWellModel : Notifier
{
    private string _API;
    public string API
    {
        get
        {
            return this._API;
        }
        set
        {
            this._API = value; OnPropertyChanged("API");
        }
    }
    private string _WellName;
    public string WellName
    {
        get
        {
            return this._WellName;
        }
        set
        {
            this._WellName = value; OnPropertyChanged("WellName");
        }
    }

    private string _Division;
    public string Division
    {
        get
        {
            return this._Division;
        }
        set
        {
            this._Division = value; OnPropertyChanged("Dvision");
        }
    }

    private string _Area;
    public string Area
    {
        get
        {
            return this._Area;
        }
        set
        {
            this._Area = value; OnPropertyChanged("Area");
        }
    }

    private string _FieldOffice;
    public string FieldOffice
    {
        get
        {
            return this._FieldOffice;
        }
        set
        {
            this._FieldOffice = value; OnPropertyChanged("FieldOffice");
        }
    }...............

**将被放入列表中以注入树视图的模型**

public class groupingModel : Notifier
{

    private string _Header;

    public string Header
    {
        get { return _Header; }
        set { _Header = value; OnPropertyChanged("Header"); }
    }


    private List<WVWellModel> _Wells;

    public List<WVWellModel> Wells
    {
        get { return _Wells; }
        set { _Wells = value; OnPropertyChanged("Wells"); }
    }

}

要注入树视图的自定义类型列表

列出treeViewList = someMethod();

总之,我想将我的树视图绑定到自定义列表对象。List<groupingModel>这些列表中的对象有两个属性,一个字符串标头,用于在树视图中对对象进行分组,以及包含自定义对象列表“WVWellModel”的第二个属性。

编辑XAML以允许选择组中的所有项目

我试图继续进行,并且可以选择群组,目标是如果选择了群组,则在下面选择所有孩子。我成功地将它绑定到名为“IsChecked”的组内的属性。它默认为false并且成功运行。问题是我无法捕获值的变化,因此无法运行任何逻辑来选择其子项。

<TreeView DockPanel.Dock="Bottom" ItemsSource="{Binding Groups}">
    <TreeView.ItemTemplate>
        <HierarchicalDataTemplate DataType="wellModel:WellGroupModel" ItemsSource="{Binding Wells}">

            **<CheckBox Content="{Binding Header}" IsChecked="{Binding IsChecked}"/>**
            <HierarchicalDataTemplate.ItemTemplate>
                <DataTemplate DataType="{x:Type wellModel:WellModel}">
                    <CheckBox Content="{Binding WellName}" IsChecked="{Binding IsSelected}" />
                </DataTemplate>
            </HierarchicalDataTemplate.ItemTemplate>
        </HierarchicalDataTemplate>
    </TreeView.ItemTemplate>

</TreeView>

1 个答案:

答案 0 :(得分:1)

TreeView控件使用HierarchicalDataTemplate来控制项目的显示方式以及子项的填充方式。如果您的item类具有不同类型的子级,则它可以指定自己的子级ItemTemplate,依此类推。

我还添加了一个最小的顶级视图模型,它拥有一个GroupingModel的集合。我正在使用传统的C#命名约定:类和属性以大写字母开头,私有字段以下划线和小写字母开头。这看起来很傻但是当每个人都使用相同的约定时,你总会知道你在看什么。

最后,我使用ObservableCollection<T>而不是List<T>。如果将ObservableCollection绑定到控件,则可以添加/删除集合中的项目,控件将自动得到通知并自行更新,而无需您执行任何其他工作。

XAML

<TreeView
    ItemsSource="{Binding Groups}"
    >
    <TreeView.ItemTemplate>
        <HierarchicalDataTemplate
            DataType="{x:Type local:GroupingModel}"
            ItemsSource="{Binding Wells}"
            >
            <TextBlock Text="{Binding Header}" />
            <HierarchicalDataTemplate.ItemTemplate>
                <!-- This can be DataTemplate if no child collection is specified -->
                <DataTemplate
                    DataType="{x:Type local:WVWellModel}"
                    >
                    <TextBlock Text="{Binding WellName}" />
                </DataTemplate>
            </HierarchicalDataTemplate.ItemTemplate>
        </HierarchicalDataTemplate>
    </TreeView.ItemTemplate>
</TreeView>

或者,如果您有异构的对象集合,则可以将隐式模板创建为资源,并按类型而不是按层次结构应用它们。在您的特定情况下,这将产生相同的结果,因为您有一个严格的项目层次结构。

<TreeView
    ItemsSource="{Binding Groups}"
    >
    <TreeView.Resources>
        <HierarchicalDataTemplate
            DataType="{x:Type local:GroupingModel}"
            ItemsSource="{Binding Wells}"
            >
            <TextBlock Text="{Binding Header}" />
        </HierarchicalDataTemplate>
        <DataTemplate
            DataType="{x:Type local:WVWellModel}"
            >
            <TextBlock Text="{Binding WellName}" />
        </DataTemplate>
    </TreeView.Resources>
</TreeView>

C#

public class ViewModel : Notifier
{
    public ViewModel()
    {
        Groups = new ObservableCollection<GroupingModel>
        {
            new GroupingModel {
                Header = "First Group",
                Wells = new List<WVWellModel> {
                    new WVWellModel() { WellName = "First Well" },
                    new WVWellModel() { WellName = "Second Well" },
                    new WVWellModel() { WellName = "Third Well" },
                }
            },
            new GroupingModel {
                Header = "Second Group",
                Wells = new List<WVWellModel> {
                    new WVWellModel() { WellName = "Third Well" },
                    new WVWellModel() { WellName = "Fourth Well" },
                    new WVWellModel() { WellName = "Fifth Well" },
                }
            }
        };
    }

    #region Groups Property
    private ObservableCollection<GroupingModel> _groups = new ObservableCollection<GroupingModel>();
    public ObservableCollection<GroupingModel> Groups
    {
        get { return _groups; }
        set
        {
            if (value != _groups)
            {
                _groups = value;
                OnPropertyChanged(nameof(Groups));
            }
        }
    }
    #endregion Groups Property
}

更新

让我们检查WVWellModel个项目。首先,我们将为它们提供一个布尔属性,我们将绑定到复选框的IsChecked属性:

public class WVWellModel : Notifier
{
    private bool _isSelected;
    public bool IsSelected
    {
        get
        {
            return this._isSelected;
        }
        set
        {
            this._isSelected = value; OnPropertyChanged();
        }
    }

然后我们会将WVWellModel DataTemplate中的内容从TextBlock更改为CheckBox

<DataTemplate
    DataType="{x:Type local:WVWellModel}"
    >
    <CheckBox 
        Content="{Binding WellName}" 
        IsChecked="{Binding IsSelected}"
        />
</DataTemplate>

只要有一个根元素,您就可以将任何有效的XAML UI放在模板中。

<TreeView
    Width="300"
    Height="200"
    ItemsSource="{Binding Groups}"
    Grid.IsSharedSizeScope="True"
    >
    <TreeView.Resources>
        <HierarchicalDataTemplate
            DataType="{x:Type local:GroupingModel}"
            ItemsSource="{Binding Wells}"
            >
            <TextBlock Text="{Binding Header}" />
        </HierarchicalDataTemplate>
        <DataTemplate
            DataType="{x:Type local:WVWellModel}"
            >
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto" SharedSizeGroup="CheckBoxColumn" />
                    <ColumnDefinition Width="Auto" SharedSizeGroup="APIColumn" />
                </Grid.ColumnDefinitions>
                <CheckBox 
                    Grid.Column="0"
                    Content="{Binding WellName}" 
                    IsChecked="{Binding IsSelected}"
                    />
                <TextBlock 
                    Grid.Column="1"
                    Margin="12,0,0,0"
                    Text="{Binding API}" 
                    HorizontalAlignment="Right"
                    />
            </Grid>
        </DataTemplate>
    </TreeView.Resources>
</TreeView>