如何实现始终在启动时或过滤后在树视图中展开前2个节点

时间:2014-09-23 01:34:35

标签: c# wpf mvvm treeview

我有一个带有mvvm和collection的示例项目来构建树视图。

我想知道如何实现在开始或过滤树视图后始终展开前2个节点。

XAML

<Window x:Class="WpfTVHierarchicalDataTemplateFilter.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:loc ="clr-namespace:WpfTVHierarchicalDataTemplateFilter"
    Title="MainWindow" Height="350" Width="525">
<StackPanel Orientation="Vertical">
    <StackPanel Orientation="Vertical">
        <CheckBox Content="Green" Margin="2" IsChecked="{Binding Path=IsDisplayGreen, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
        <CheckBox Content="Yellow" Margin="2" IsChecked="{Binding Path=IsDisplayYellow, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
        <CheckBox Content="Red" Margin="2" IsChecked="{Binding Path=IsDisplayRed, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" IsEnabled="False" />
    </StackPanel>
    <TreeView ItemsSource="{Binding ClassList}">
        <TreeView.Resources>
            <HierarchicalDataTemplate DataType="{x:Type loc:Class}" ItemsSource="{Binding Students}">
                <StackPanel Orientation="Horizontal">
                    <Image Margin="2" Source="{Binding ImagePath}"></Image>
                    <TextBlock Margin="2" Text="{Binding Name}"></TextBlock>
                </StackPanel>
            </HierarchicalDataTemplate>

            <HierarchicalDataTemplate DataType="{x:Type loc:Student}">
                <StackPanel Orientation="Horizontal">
                    <Image Margin="2" Source="{Binding ImagePath}"></Image>
                    <TextBlock Margin="2" Text="{Binding Name}" ToolTip="{Binding ToolTip}"></TextBlock>
                </StackPanel>
            </HierarchicalDataTemplate>
        </TreeView.Resources>
    </TreeView>
</StackPanel>

查看模型

public class MainWindowViewModel : PropertyChangedBase
{
    private bool _isDisplayGreen = true;
    private bool _isDisplayRed = true;
    private bool _isDisplayYellow = true;

    public bool IsDisplayGreen
    {
        get { return _isDisplayGreen; }
        set
        {
            _isDisplayGreen = value;
            FilterFunction();
            OnPropertyChanged("IsDisplayRed");
            OnPropertyChanged("IsDisplayGreen");
            OnPropertyChanged("IsDisplayYellow");
        }
    }

    public bool IsDisplayRed
    {
        get { return _isDisplayRed; }
        set
        {
            _isDisplayRed = value;
            FilterFunction();
            OnPropertyChanged("IsDisplayRed");
            OnPropertyChanged("IsDisplayGreen");
            OnPropertyChanged("IsDisplayYellow");
        }
    }

    public bool IsDisplayYellow
    {
        get { return _isDisplayYellow; }
        set
        {
            if (value == false)
            {
                _isDisplayGreen = value;
            }

            _isDisplayYellow = value;
            FilterFunction();
            OnPropertyChanged("IsDisplayRed");
            OnPropertyChanged("IsDisplayGreen");
            OnPropertyChanged("IsDisplayYellow");
        }
    }

    private void FilterFunction()
    {
        ICollectionView classesDataSourceView = CollectionViewSource.GetDefaultView(ClassList);

        classesDataSourceView.Filter = (classModel =>
        {
            ICollectionView studentsDataSourceView = CollectionViewSource.GetDefaultView(((Class)classModel).Students);

            if (_isDisplayGreen == false && _isDisplayYellow == false && _isDisplayRed == false)
            {
                studentsDataSourceView.Filter = (studentModel => false);
            }

            if (_isDisplayGreen == true && _isDisplayYellow == true && _isDisplayRed == true)
            {
                studentsDataSourceView.Filter = (studentModel => true);
            }

            if (_isDisplayGreen == false && _isDisplayYellow == true && _isDisplayRed == false)
            {
                studentsDataSourceView.Filter = (studentModel => ((Student)studentModel).ImagePath.Equals("../Images/Yellow-icon.png"));
            }

            if (_isDisplayGreen == true && _isDisplayYellow == false && _isDisplayRed == false)
            {
                studentsDataSourceView.Filter = (studentModel => ((Student)studentModel).ImagePath.Equals("../Images/Green-icon.png"));
            }

            if (_isDisplayGreen == false && _isDisplayYellow == false && _isDisplayRed == true)
            {
                studentsDataSourceView.Filter = (studentModel => ((Student)studentModel).ImagePath.Equals("../Images/Red-icon.png"));
            }

            if (_isDisplayGreen == true && _isDisplayYellow == false && _isDisplayRed == true)
            {
                studentsDataSourceView.Filter = (studentModel => ((Student)studentModel).ImagePath.Equals("../Images/Red-icon.png") || ((Student)studentModel).ImagePath.Equals("../Images/Green-icon.png"));
            }

            if (_isDisplayGreen == false && _isDisplayYellow == true && _isDisplayRed == true)
            {
                studentsDataSourceView.Filter = (studentModel => ((Student)studentModel).ImagePath.Equals("../Images/Red-icon.png") || ((Student)studentModel).ImagePath.Equals("../Images/Yellow-icon.png"));
            }

            if (_isDisplayGreen == true && _isDisplayYellow == true && _isDisplayRed == false)
            {
                studentsDataSourceView.Filter = (studentModel => ((Student)studentModel).ImagePath.Equals("../Images/Yellow-icon.png") || ((Student)studentModel).ImagePath.Equals("../Images/Green-icon.png"));
            }

            return !studentsDataSourceView.IsEmpty;
        });
    }

    private ObservableCollection<Class> classList;

    public ObservableCollection<Class> ClassList
    {
        get { return classList; }
        set { classList = value; }
    }

    public MainWindowViewModel()
    {
        classList = GetAll();
    }

    public ObservableCollection<Class> GetAll()
    {
        ObservableCollection<Class> classList = new ObservableCollection<Class>();
        Class treeItem = null;
        string greenIconPath = "../Images/Green-icon.png";
        string redIconPath = "../Images/Red-icon.png";
        string yellowIconPath = "../Images/Yellow-icon.png";

        treeItem = new Class("Class A", redIconPath);
        treeItem.Students.Add(new Student("Student 1", greenIconPath));
        treeItem.Students.Add(new Student("Student 2", greenIconPath));
        treeItem.Students.Add(new Student("Student 3", redIconPath));
        classList.Add(treeItem);

        treeItem = new Class("Class B", yellowIconPath);
        treeItem.Students.Add(new Student("Student 1", yellowIconPath));
        treeItem.Students.Add(new Student("Student 2", greenIconPath));
        treeItem.Students.Add(new Student("Student 3", greenIconPath));
        classList.Add(treeItem);

        treeItem = new Class("Class C", greenIconPath);
        treeItem.Students.Add(new Student("Student 1", greenIconPath));
        treeItem.Students.Add(new Student("Student 2", greenIconPath));
        treeItem.Students.Add(new Student("Student 3", greenIconPath));
        classList.Add(treeItem);

        return classList;
    }
}

Sample project

1 个答案:

答案 0 :(得分:1)

您可以通过绑定来完成此操作。使用TreeView.ItemContainerStyle属性:

<TreeView ItemsSource="{Binding ClassList}">
    <TreeView.ItemContainerStyle>
        <Style TargetType="{x:Type TreeViewItem}">
            <Setter Property="IsExpanded" Value="{Binding Path=IsExpanded, Mode=TwoWay}"/>
        </Style>
    </TreeView.ItemContainerStyle>
    <TreeView.Resources>
        <HierarchicalDataTemplate DataType="{x:Type loc:Class}" ItemsSource="{Binding Students}">
            <StackPanel Orientation="Horizontal">
                <Image Margin="2" Source="{Binding ImagePath}">
                </Image>
                <TextBlock Margin="2" Text="{Binding Name}">
                </TextBlock>
            </StackPanel>
        </HierarchicalDataTemplate>
        <HierarchicalDataTemplate DataType="{x:Type loc:Student}">
            <StackPanel Orientation="Horizontal">
                <Image Margin="2" Source="{Binding ImagePath}">
                </Image>
                <TextBlock Margin="2" Text="{Binding Name}" ToolTip="{Binding ToolTip}">
                </TextBlock>
            </StackPanel>
        </HierarchicalDataTemplate>
    </TreeView.Resources>
</TreeView>

然后,您必须在Class和Student ViewModel上放置一个IsExpanded属性。这些应该在更改时通知属性更改事件,因此需要扩展INotifyPropertyChanged,例如。

public bool IsExpanded
{
    get
    {
        return m_IsExpanded;
    }
    set
    {
        if (Equals(m_IsExpanded, value))
        {
            return;
        }

        m_IsExpanded = value;

        NotifyPropertyChanged("IsExpanded");
    }
}

然后,您可以在应用过滤器时要扩展的对象上设置Class.IsExpanded = true(或者在ViewModel中随时设置)。