Click here to Skip to main content
15,885,032 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
Hey all! This is a simple MVVM treeview project which displays (is supposed to display!) a treeView of Tasks and a textbox showing the Task contents (TaskName for instance). The problem is that the tree items are not shown at all! These are the classes used:
C#
public class TaskTreeViewModel
{
    TaskViewModel vmRooT;
    List<TaskViewModel> vmFirstGeneration;
    public TaskTreeViewModel(Task rootTask)
    {
        vmRooT = new TaskViewModel(rootTask);
        vmFirstGeneration = new List<TaskViewModel>(new TaskViewModel[] { vmRooT });

    }
}

C#
class TaskViewModel : INotifyPropertyChanged
{
    private Task vmTask;    
    private List<TaskViewModel> vmSubTasks;
    TaskViewModel vmParent;
    //Task status
    bool vmIsExpanded;
    bool vmIsSelected;

    #region properties

    public string Name
    {
        get
        {return vmTask.TaskName;}
    }
    public List<TaskViewModel> SubTasks
    {
        get
        {return vmSubTasks;}
    }
    public TaskViewModel Parent
    {
        get
        {return vmParent;}
    }
    #endregion

    #region ctors

    private TaskViewModel(Task task, TaskViewModel parent)
    {
        vmTask = task; 
        vmParent = parent; 
        ///<summary>
        ///recursively walks down the Task tree, wrapping each Task object in a TaskViewModel
        ///</summary>
        vmSubTasks = new List<TaskViewModel>( 
                (from t in vmTask.SubTasks
                 select new TaskViewModel(t, this)).ToList<TaskViewModel>());          
    }
    public TaskViewModel(Task task)
        : this(task, null)
    { }

    #endregion

    #region Presentation Members

    /// <summary>
    /// Gets/sets whether the TreeViewItem 
    /// associated with this object is expanded.
    /// </summary>
    public bool IsExpanded
    {
        get { return vmIsExpanded; }
        set
        {
            if (value != vmIsExpanded)
            {
                vmIsExpanded = value;
                this.OnPropertyChanged("IsExpanded");
            }

            // Expand all the way up to the root.
            if (vmIsExpanded && vmParent != null)
                vmParent.vmIsExpanded = true;   //fantastic! (executes the setter again)
        }
    }
    /// <summary>
    /// Gets/sets whether the TreeViewItem 
    /// associated with this object is selected.
    /// </summary>
    public bool IsSelected
    {
        get { return vmIsSelected; }
        set
        {
            if (value != vmIsSelected)
            {
                vmIsSelected = value;
                this.OnPropertyChanged("IsSelected");
            }
        }
    }

    #endregion

    #region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void OnPropertyChanged(string propertyName)
    {
        if (this.PropertyChanged != null)
            this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }

    #endregion 
}

C#
public class Task
{
    //auto-implemented properites
    public string TaskName { get; set; }
    public string Description { get; set; }
    public List<Task> SubTasks { get; set; }
    #region ctors
    public Task()
    {
        TaskName = string.Empty;
        Description = string.Empty;
        SubTasks = new List<Task>();    
    }
    public Task(string strTaskName)
        : this()
    {
        TaskName = strTaskName;
    }
    public Task(string strTaskName, string strDescription)
        : this(strTaskName)
    {
        Description = strDescription;       
    }
    public Task(string strTaskName, List<Task> subs)
        : this(strTaskName)
    {
        SubTasks = subs;
    }
    public Task(string strTaskName, string strDescription, List<Task> subs)
        : this(strTaskName, strDescription)
    {
        SubTasks = subs;
    }
    public Task(string strTaskName, string strDescription, params string[] strSubTasksNames)
        : this(strTaskName, strDescription)
    {
        SubTasks = new List<Task>();
        foreach (var strSub in strSubTasksNames)
        {
            SubTasks.Add(new Task(strSub));
        }
    }
    #endregion ctors
}

And these are the XAML file and its code-behind:
C#
<Window x:Class="Task_it__with_MVVM_.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Task it!" Height="570" Width="850" WindowStartupLocation="CenterScreen">
    
    <Grid FlowDirection="RightToLeft" Margin="10">
        <Grid.ColumnDefinitions>
            <ColumnDefinition></ColumnDefinition>
            <ColumnDefinition></ColumnDefinition>
        </Grid.ColumnDefinitions>
            <TreeView Name="tvTasks" Grid.Column="0" Margin="10" MinHeight="280" ItemsSource="{Binding vmFirstGeneration}">
                <TreeView.ItemContainerStyle>
                    <Style TargetType="{x:Type TreeViewItem}">
                        <Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}" />
                        <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" />
                        <Setter Property="FontWeight" Value="Normal" />
                        <Style.Triggers>
                            <Trigger Property="IsSelected" Value="True">
                                <Setter Property="FontWeight" Value="Bold" />
                            </Trigger>
                        </Style.Triggers>
                    </Style>
                </TreeView.ItemContainerStyle>
                <TreeView.ItemTemplate>
                    <HierarchicalDataTemplate ItemsSource="{Binding SubTasks}">
                        <TextBlock Text="{Binding Name}" FontSize="14"/>
                    </HierarchicalDataTemplate>
                </TreeView.ItemTemplate>
                
            </TreeView>
        <GroupBox Grid.Column="1" Header="details" Margin="10">
            <StackPanel Margin="10" DataContext="{Binding ElementName=tvTasks, Path=SelectedItem}" >
                <StackPanel Margin="1">
                    <Label FontSize="14" Margin="1">Name</Label>
                    <TextBox Name="txtName"  Text="{Binding Name}" FontSize="16" Margin="1" Width="auto">
                    </TextBox>
                </StackPanel>
            </StackPanel>
        </GroupBox>
    </Grid>

</Window>

code-behind:
C#
public partial class MainWindow : Window
{
    //RootTask which is the fixed permanent Task at the root
    public Task RootTask { get; set; }
    TaskTreeViewModel vmTaskTree { get; set; }
    //ctor
    public MainWindow()
    {
        InitializeComponent();
        PrepareTree_Data();
    }
    public void PrepareTree_Data()
    {
        // Get raw task tree data
        RootTask = SaveLoad.LoadData();//This is method just initializes the RootTask
        // Create UI-friendly wrappers around the
        // raw data objects (i.e. the view-model).
        vmTaskTree = new TaskTreeViewModel(RootTask);
        // Let the UI bind to the view-model.
        base.DataContext = vmTaskTree;
    }
}
Posted
Updated 21-Oct-12 21:07pm
v3
Comments
Sergey Alexandrovich Kryukov 22-Oct-12 1:23am    
Any questions?
--SA
cs101000 22-Oct-12 2:54am    
Oh yes, itemsSource property is not functionning, I dont see the treeviewItems.
cs101000 23-Oct-12 12:46pm    
Can you take a look at this? I had told you a little about it before:
http://www.codeproject.com/Questions/482573/Howplustoplussave-2floadplusanplusobject

1 solution

Hi,

Solution is very simple. Just change all List<t> to "ObservableCollection<t>.

Regards,
Tarik
 
Share this answer
 
Comments
cs101000 23-Oct-12 8:54am    
Oh, thanks a lot! Although this ObservableCollection didn't solve this code's issue but it helped me in another code very much!
best regards

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900