簡體   English   中英

XAML定義以使用MVVM構建TreeView

[英]XAML definition to build a TreeView with MVVM

我正在嘗試在WPF應用程序中使用MVVM構建TreeView,但不了解如何處理HierarchicalDataTemplate 我的TreeView應該代表一個文件夾結構,其中包含文件夾內的文件夾,依此類推。

我的文件夾ViewModel定義如下:

public class TreeViewFolderViewModel : ViewModelBase
{
    private int _id;
    private int _parentId;
    private string _text;
    private string _key;
    private ObservableCollection<TreeViewFolderViewModel> _children;

    public int Id
    {
        get { return this._id; }
        set { Set(() => Id, ref this._id, value); }
    }

    public int ParentId
    {
        get { return this._parentId; }
        set { Set(() => ParentId, ref this._parentId, value); }
    }

    public string Text
    {
        get { return this._text; }
        set { Set(() => Text, ref this._text, value); }
    }

    public string Key
    {
        get { return this._key; }
        set { Set(() => Key, ref this._key, value); }
    }

    public ObservableCollection<TreeViewFolderViewModel> Children
    {
        get { return this._children ?? (this._children = 
              new ObservableCollection<TreeViewFolderViewModel>()); }
        set { Set(() => Children, ref this._children, value); }
    }
}

我的模型與ViewModel具有相同的結構,因此最終的ViewModel是包含子文件夾等的文件夾列表。 我正在使用遞歸加載所有這些文件夾,並且該部分工作正常。

我遇到的問題是如何定義此ViewModel並將其加載到實際的TreeView中。

我已經使用MVVM模式閱讀了TreeView中的Hierarchical DataBinding,雖然我或多或少都了解發生了什么,但是TreeView每個級別都代表一種不同的對象類型,而我的TreeView只有一種對象類型,我對此感到困惑我怎么定義這個。

我MainWindowViewModel中的Root ViewModel屬性的類型為TreeViewFolderViewModel ,這意味着我只有一個對象,它代表我的TreeView的根。 該對象具有TreeViewFolderViewModel類型的子級,而子類又具有TreeViewFolderViewModel類型的子級,依此類推

我如何在XAML定義它? 我有以下定義:

<TreeView Grid.Row="1" Margin="5,0,5,5" ItemsSource="{Binding RootFolder}"/>

我有一個定義如下的Hierarchical模板:

<Window.Resources>
    <HierarchicalDataTemplate ItemsSource="{Binding Children}" 
     DataType="{x:Type viewmodels:SharePointFolderTreeViewViewModel}">
        <Label Content="{Binding Name}"/>
    </HierarchicalDataTemplate>
</Window.Resources>

但是什么都沒有加載。

關於如何解決此問題的任何想法?

謝謝。

我准備了一個小樣本來說明。

視圖模型

public class TreeViewFolderViewModel : ViewModelBase
{
    private int id;
    public int Id
    {
        get { return id; }
        set { id = value; OnPropertyChanged("Id"); }
    }

    private string text;
    public string Text
    {
        get { return text; }
        set { text = value; OnPropertyChanged("Text"); }
    }

    private ObservableCollection<TreeViewFolderViewModel> children;
    public ObservableCollection<TreeViewFolderViewModel> Children
    {
        get
        {
            return children ?? (children =
            new ObservableCollection<TreeViewFolderViewModel>());
        }
        set { children = value; OnPropertyChanged("Children"); }
    }
}

public class TreeViewModel : ViewModelBase
{
    private List<TreeViewFolderViewModel> items;
    public List<TreeViewFolderViewModel> Items
    {
        get { return items; }
        set { items = value; OnPropertyChanged("Items"); }
    }

    public TreeViewModel()
    {
        Items = new List<TreeViewFolderViewModel>()
        {
            new TreeViewFolderViewModel()
            {
                Id =0, Text="RootFolder", Children=new ObservableCollection<TreeViewFolderViewModel>()
                {
                    new TreeViewFolderViewModel() { Id = 10, Text = "FirstFolder", Children=new ObservableCollection<TreeViewFolderViewModel>() { new TreeViewFolderViewModel() { Id = 11, Text = "FirstChild" } } } ,
                    new TreeViewFolderViewModel() { Id = 20, Text = "SecondFolder", Children = new ObservableCollection<TreeViewFolderViewModel>() { new TreeViewFolderViewModel() { Id = 21, Text = "SecondChild" } } } ,
                    new TreeViewFolderViewModel() { Id = 30, Text = "ThirdFolder", Children = new ObservableCollection<TreeViewFolderViewModel>() { new TreeViewFolderViewModel() { Id = 31, Text = "ThirdChild" } } }
                }
            }
        };
    }
}

public class ViewModelBase : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged(string propName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName));
    }
}

MainWindow.xaml

<Window x:Class="WpfApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfApp"
        Title="MainWindow" Height="350" Width="525">
    <Window.DataContext>
        <local:TreeViewModel />
    </Window.DataContext>

    <Window.Resources>    
        <HierarchicalDataTemplate ItemsSource="{Binding Children}" 
                                  DataType="{x:Type local:TreeViewFolderViewModel}">
            <TextBlock>
                <TextBlock.Text>
                    <MultiBinding StringFormat="{}{0} {1}">
                        <Binding Path="Id" />
                        <Binding Path="Text" />
                    </MultiBinding>
                </TextBlock.Text>
            </TextBlock>
        </HierarchicalDataTemplate>    
    </Window.Resources>

    <Grid>
        <TreeView ItemsSource="{Binding Items}" />
    </Grid>
</Window>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM