0

I have recursive ObservableCollection representing directories and files. My idea - if user Checked file, parent directories should know about this.

ViewModel: class that contains Root Collection

 public class DirectoryTreeViewModel : BaseViewModel
    {
        readonly ObservableCollection<DirectoryViewModel> _rootDirectories;

        public ObservableCollection<DirectoryViewModel> RootDirectory
        {
            get { return _rootDirectories; }
        }

classes representing Directories and Files

  public class DirectoryViewModel: BaseViewModel
    {
        readonly ObservableCollection<DirectoryViewModel> _childNode;
        readonly ObservableCollection<FileViewModel> _childFile;
        readonly DirectoryViewModel _parentNode;
        readonly Directory _directory;

        public DirectoryViewModel(Directory directory)
            :this(directory, null)
        {
            
        }

   

        private DirectoryViewModel(Directory directory, DirectoryViewModel parentNode)
        {
            _directory = directory;
            _parentNode = parentNode;
            _childNode = new ObservableCollection<DirectoryViewModel>();
            _childFile = new ObservableCollection<FileViewModel>();
            foreach (Directory dir in directory.directories )
            {
                _childNode.Add(new DirectoryViewModel(dir, this));
            }

            foreach (File file in directory.files)
            {
                _childFile.Add(new FileViewModel(file, this));
            }

        }
     

        public ObservableCollection<DirectoryViewModel> ChildNodes
        {
            get { return _childNode; }
        }
        public ObservableCollection<FileViewModel> ChildFiles
        {
            get { return _childFile; }
        }
       
        public ObservableCollection<object> Nodes
        {
            get
            {
                ObservableCollection<object> childNodes = new ObservableCollection<object>();
                foreach (var dir in this.ChildNodes)
                    childNodes.Add(dir);
                foreach (var file in this.ChildFiles)
                    childNodes.Add(file);
                return childNodes;
            }
        }

        public Directory Directory
        {
            get => _directory;
        }
        public string Name
        {
            get { return _directory.Name; }
        }
        public string ImageSource
        {
            get { return _imageSource; }
        }

        public string Path
        {
            get { return _directory.Path; }
        }

        public bool Checked
        {
            get => _directory.Checked;
            set => _directory.Checked = value;
        }
       public bool hasCheckedFile
        {
            get => Directory.HasCheckedFile;
            set => Directory.HasCheckedFile = value;
        }
        
        public bool HasCheckedFile
        {
            get { return hasCheckedFile; }
            set
            {

                hasCheckedFile = value;
                if (_parentNode != null)
                    _parentNode.hasCheckedFile = hasCheckedFile;
                OnPropertyChanged(nameof(HasCheckedFile));
            }
        }

        

    }


    public class FileViewModel: BaseViewModel
    {
        readonly DirectoryViewModel _parentNode;
        readonly File _file;

        public FileViewModel(File file, DirectoryViewModel parentNode)
        {
            _parentNode = parentNode;
            _file = file;
        }
        public string Name
        {
            get { return _file.Name; }
        }

        
        public string ImageSource
        {
            get { return _imageSource; }
        }
        
        public string FullPath
        {
            get { return _file.FullPath; }
        }

        public bool Checked
        {
            get => _file.Checked;
            set => _file.Checked=value;
        }


        public bool IsCheckedToCopy
        {
            get { return Checked; }
            set
            {
                if (value == true)
                {
                    _parentNode.HasCheckedFile = true;
                    Checked = true;
                }

                else if (value == false)
                {
                    Checked = false;
                }

                _file.Checked = value;
                OnPropertyChanged(nameof(IsCheckedToCopy));

            }
        }
    }
}

View

 <TreeView x:Name="treeView1" MaxHeight="700" Margin="4,117,-2,-28" ItemsSource="{Binding RootDirectory}" FontSize="12" >
                    <TreeView.DataContext>
                        <VM:DirectoryTreeViewModel/>
                    </TreeView.DataContext>
                    <TreeView.ItemTemplate>
                        <HierarchicalDataTemplate ItemsSource="{Binding Nodes}">
                            <CheckBox x:Name="CopyChBox"  IsChecked="{Binding IsCheckedToCopy, Mode=TwoWay}" >
                               
                                <Grid>
                                    <Grid.ColumnDefinitions>
                                        <ColumnDefinition Width="*"/>
                                        <ColumnDefinition/>
                                        <ColumnDefinition/>
                                    </Grid.ColumnDefinitions>
                                    <Image Grid.Column="0" Width="20" Margin="1" Source="{Binding ImageSource}"/>
                                    <TextBlock Grid.Column="1" VerticalAlignment="Center" Text="{Binding Name}"/>


                                </Grid>
                            </CheckBox>

                        </HierarchicalDataTemplate>

                    </TreeView.ItemTemplate>
                </TreeView>

If i try to change collection item properties, my root collection "_rootdirectories" (ItemSource for TreeView) does not change. How to implement listener so root collection knows about changes in collection items?

While Binding works well and all data from RooDirectory displayed, If i try to change collection item properties, my root collection "_rootdirectories" (ItemSource for TreeView) does not change. ObservableCollection knows about adding and deleting items, but i don't know how to implement listener so root collection will knew about changes in items properties made from View? Is it possible? Or is it better to use BindingList instead ObservableCollection?

  • [link](https://stackoverflow.com/a/4284805/17350254) refer to BindingList vs ObservableCollection and with the TreeView you would like to achieve something like this I believe [link](https://stackoverflow.com/a/28613398/17350254) – radoczsanyi_ Aug 16 '23 at 14:10
  • How is the collection supposed to change when you set a property of an individual item? Or what do you mean? What exactly is your issue? – mm8 Aug 16 '23 at 14:17

0 Answers0