使用MVVM单击按钮时绑定WPF TreeView

时间:2017-10-24 21:43:11

标签: wpf mvvm data-binding

我正在构建WPF应用程序,我正在使用MVVM模式进行数据绑定和命令绑定。

当我在构造函数(LoadTreeViewViewModel)中绑定树视图时,它没有任何问题,但是当我在Button中执行相同操作时,它不起作用。我做了一些研究,我也绑定到listview,绑定工作没有问题列表视图按钮点击。所以问题只在于TreeView绑定

以下是示例应用程序的完整代码。

  

XAML

<Window x:Class="WpfApp1.LoadTreeView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApp1"
        mc:Ignorable="d"
        Title="LoadTreeView" Height="300" Width="300">
    <Window.DataContext>
        <local:LoadTreeViewViewModel></local:LoadTreeViewViewModel>
    </Window.DataContext>
    <Window.Resources>
        <local:LoadTreeViewViewModel x:Key="viewModel"></local:LoadTreeViewViewModel>
    </Window.Resources>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"></ColumnDefinition>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="5*"></RowDefinition>
            <RowDefinition Height="5*"></RowDefinition>
            <RowDefinition Height="1*"></RowDefinition>
        </Grid.RowDefinitions>

        <TreeView ItemsSource="{Binding Folders}" Grid.Column="0" Grid.Row="0">
            <TreeView.ItemTemplate>
                <HierarchicalDataTemplate ItemsSource="{Binding Folders}" DataType="{x:Type local:IFolder}">
                    <TreeViewItem Header="{Binding FolderLabel}"/>
                </HierarchicalDataTemplate>
            </TreeView.ItemTemplate>
        </TreeView>

        <ListView VerticalAlignment="Top" Grid.Column="0" Grid.Row="1"
                  ItemsSource="{Binding Lists, Source={StaticResource viewModel}}">
            <ListView.View>
                <GridView>
                    <GridViewColumn/>
                </GridView>
            </ListView.View>
        </ListView>

        <Button Content="Button" HorizontalAlignment="Left" VerticalAlignment="Top" Width="75" 
                Grid.Column="0" Grid.Row="2"
                Command="{Binding LoadSourceCommand, Source={StaticResource viewModel}}"/>
    </Grid>
</Window>
  

LoadTreeView

public partial class LoadTreeView : Window
{
    public LoadTreeView()
    {
        InitializeComponent();
        //this.DataContext = new LoadTreeViewViewModel();
    }
}
  

的iFolder

public interface IFolder
{
    List<IFolder> Folders { get; set; }
    string FolderLabel { get; set; }
    string FullPath { get; set; }
}
  

文件夹

public class Folder : IFolder
{
    public List<IFolder> Folders { get; set; }
    public string FolderLabel { get; set; }
    public string FullPath { get; set; }

    public Folder()
    {
        Folders = new List<IFolder>();
    }
}
  

LoadTreeViewViewModel

class LoadTreeViewViewModel : INotifyPropertyChanged
    {
        public LoadTreeViewViewModel()
        {
            this.LoadSourceCommand = new ViewModel.btnClick(this.LoadData, this.IsValid);
            //this.Folders = await LoadDataAsync();
            //LoadData();
        }
        private async void LoadData()
        {
            this.Folders = await LoadTreeAsync();
            this.Lists = await LoadListAsync();
        }
        private async Task<string[]> LoadListAsync()
        {
            List<string> temp = new List<string>();

            await Task.Delay(TimeSpan.FromSeconds(3)).ConfigureAwait(false);

            //add Root items
            temp.Add("Dummy1");
            temp.Add("Dummy2");
            temp.Add("Dummy3");
            temp.Add("Dummy4");

            return temp.ToArray();
        }
        private async Task<List<IFolder>> LoadTreeAsync()
        {
            List<IFolder> temp = new List<IFolder>();

            await Task.Delay(TimeSpan.FromSeconds(3)).ConfigureAwait(false);

            //add Root items
            temp.Add(new Folder { FolderLabel = "Dummy1", FullPath = @"C:\dummy1" });
            temp.Add(new Folder { FolderLabel = "Dummy2", FullPath = @"C:\dummy2" });
            temp.Add(new Folder { FolderLabel = "Dummy3", FullPath = @"C:\dummy3" });
            temp.Add(new Folder { FolderLabel = "Dummy4", FullPath = @"C:\dummy4" });

            //add sub items
            temp[0].Folders.Add(new Folder { FolderLabel = "Dummy11", FullPath = @"C:\dummy11" });
            temp[0].Folders.Add(new Folder { FolderLabel = "Dummy12", FullPath = @"C:\dummy12" });
            temp[0].Folders.Add(new Folder { FolderLabel = "Dummy13", FullPath = @"C:\dummy13" });
            temp[0].Folders.Add(new Folder { FolderLabel = "Dummy14", FullPath = @"C:\dummy14" });

            return temp;
        }
        private bool IsValid()
        {
            return true;
        }

        #region Members
        private ViewModel.btnClick loadSourceCommand;
        public btnClick LoadSourceCommand
        {
            get { return loadSourceCommand; }
            set { loadSourceCommand = value; }
        }
        private List<IFolder> m_folders;
        public List<IFolder> Folders
        {
            get { return m_folders; }
            set
            {
                m_folders = value;
                NotifiyPropertyChanged("Folders");

            }
        }
        private string[] lists;
        public string[] Lists
        {
            get { return lists; }
            set { lists = value; NotifiyPropertyChanged("Lists"); }
        }
        #endregion

        void NotifiyPropertyChanged(string property)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(property));
        }
        public event PropertyChangedEventHandler PropertyChanged;
    }
  

btnClick

public class btnClick : System.Windows.Input.ICommand
{
    private Action WhatToExecute;
    private Func<bool> WhenToExecute;
    public btnClick(Action what, Func<bool> when)
    {
        WhatToExecute = what;
        WhenToExecute = when;
    }
    public void Refresh()
    {
        if (this.CanExecuteChanged != null)
        {
            CanExecuteChanged(this, EventArgs.Empty);
        }
    }
    public event EventHandler CanExecuteChanged;
    public bool CanExecute(object parameter)
    {
        return WhenToExecute();
    }
    public void Execute(object parameter)
    {
        WhatToExecute();
    }
}

1 个答案:

答案 0 :(得分:1)

您可能遇到绑定错误。 检查输出日志和BindingExpression错误。

我怀疑你想要使用你定义的viewModel实例,而不是窗口的datacontext,因为它们将是两个不同的实例。

<TreeView ItemsSource="{Binding Folders, Source={StaticResource viewModel}}"
          Grid.Column="0" 
          Grid.Row="0">
       <TreeView.ItemTemplate>
           <HierarchicalDataTemplate ItemsSource="{Binding Folders}"
                                     DataType="{x:Type local:IFolder}">
            <TreeViewItem Header="{Binding FolderLabel}"/>
        </HierarchicalDataTemplate>
    </TreeView.ItemTemplate>
</TreeView>