2017-10-24 3 views
0

데이터 바인딩 및 명령 바인딩을 위해 MVVM 패턴을 사용하는 WPF 응용 프로그램을 빌드하고 있습니다.MVVM에서 버튼 클릭시 WPF TreeView 바인딩 클릭

생성자 (LoadTreeViewViewModel)에서 트리보기를 바인딩하면 아무런 문제없이 작동하지만 버튼 클릭에서 동일하게 작동하면 작동하지 않습니다. 나는 listview에 바인딩하는 약간의 연구를 수행했고 바인딩은 버튼 클릭에 대한 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

01,235 16,
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

아마도 바인딩 오류가있을 수 있습니다. 출력 로그에서 BindingExpression 오류를 확인하십시오.

두 개의 서로 다른 인스턴스가 될 것이기 때문에 윈도우의 datacontext가 아닌 정의한 viewModel 인스턴스를 사용하고 싶습니다.

<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> 
관련 문제