1

I'm working on a small "fun" project using WPF/MVVM/Prism which main component is a TreeView showing the file structure of a certain path. The idea how the ViewModel works is taken from Josh Smiths' article http://www.codeproject.com/Articles/28306/Working-with-Checkboxes-in-the-WPF-TreeView.

I actually need two things:

  1. I'd like to get a list of checked items of the TreeView-View, presented in a another view (let's say List-View) and also show that the their state has changed.
  2. I'd like to modify the List-View, which shall then be reflected within the TreeView.

Somehow I did not find a nice solution, as the hierarchical ViewModel used by Josh makes it hard for me to get hold on a "shared" model useable within both ViewModels.

But let's have a look at my code before stating my question:

My "ExplorerView" uses a hierarchical datatemplate and looks as follows:

<UserControl x:Class="MyFunProject.Views.ExplorerView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:ViewModel="clr-namespace:MyFunProject.ViewModels"
             xmlns:prism="http://prismlibrary.com/"             
             prism:ViewModelLocator.AutoWireViewModel="True">
    <UserControl.Resources>
        <HierarchicalDataTemplate DataType="{x:Type ViewModel:ItemBaseViewModel}" ItemsSource="{Binding Children}">
            <StackPanel Orientation="Horizontal">
                <CheckBox Focusable="True" IsChecked="{Binding IsChecked}" VerticalAlignment="Center" ToolTip="{Binding Path}">
                    <TextBlock Text="{Binding Name}" />
                </CheckBox>
            </StackPanel>
        </HierarchicalDataTemplate>
    </UserControl.Resources>

    <TreeView ItemsSource="{Binding Children}" />

</UserControl>

Following Josh's article, the ExplorerViewModel exhibits a child as a List<CheckableItemViewModel> with only one entry - which in fact has other childs directories or files. Directories itself again have childs.

public class ExplorerViewModel : BindableBase
{
    private List<CheckableItemViewModel> childred;
    public List<CheckableItemViewModel> Children
    {
        get { return childred; }
        set { SetProperty(ref childred, value); }
    }

    public ExplorerViewModel(IExplorerModel ExplorerModel)
    {
        CheckableItemViewModel root = new CheckableItemViewModel();
        AddChildrenToNode(root, ExplorerModel.GetCheckableItems());
        root.Initialize(); // initialize children (and each children its own children, etc...)
        Children = new List<CheckableItemViewModel> { root });
    }

    private void AddChildrenToNode(CheckableItemViewModel root, IList<CheckableItem> items)
    {
        foreach(var item in items)
        {
            var child = new CheckableItemViewModel(item);
            var dirItem = item as DirectoryItem; // it's a directory and so it has childs
            if(dirItem != null)
            {
                AddChildrenToNode(child, dirItem.Items);
            }
            root.Children.Add(child);
        }
    }
}

And now to my questions:

  1. How do I connect my CheckableItemViewModel to a "kind of" global CheckableItemModel? If I inject the constructor by resolving a registered instance (unity container) I've got the problem, that I cannot do that if I'd like to have two ExplorerViews simultanously (or don't I?).
  2. How do I inject if every CheckableItemViewModel also needs constructor parameters (is this the case where to use parameter override?)
  3. How do I get a retrieve a list of the actual selected items (or when and where should I update the according model)?
  4. How do I get a "changed" flag if one of the CheckableItemViewModel is altered?

Let me know if i missed a piece of my puzzle.

Thanks for any suggestions.

ohmmega
  • 55
  • 6

0 Answers0