2017-05-06 3 views
2

MVVMパターンを使用してlistviewを生成する方法を質問したいと思います。私はmvvmパターンの初心者です。私はwpfを使用する前にこれをやったが、私はコードの背後にある。mvvmを使用してリストビューを作成する

私はMvvm Lightを使用しています。どのような私が欲しいのはこれまでのところ、私はすでにフォルダの参照

を持っている私は、このコード

public class OpenFileDialogVM : ViewModelBase 
    { 
     public static RelayCommand OpenCommand { get; set; } 
     private string _selectedPath; 
     public string SelectedPath 
     { 
      get { return _selectedPath; } 
      set 
      { 
       _selectedPath = value; 
       RaisePropertyChanged("SelectedPath"); 
      } 
     } 

     private string _defaultPath; 

     public OpenFileDialogVM() 
     { 
      RegisterCommands(); 
     } 

     public OpenFileDialogVM(string defaultPath) 
     { 
      _defaultPath = defaultPath; 
      RegisterCommands(); 
     } 

     private void RegisterCommands() 
     { 
      OpenCommand = new RelayCommand(ExecuteOpenFileDialog); 
     } 

     private void ExecuteOpenFileDialog() 
     { 
      var dialog = new FolderBrowserDialog(); 
      dialog.ShowDialog(); 

      SelectedPath = dialog.SelectedPath; 
     } 
    } 

と私きを持っているフォルダの場所を閲覧し、それ

内のファイルをリストビューに移入されこのユーザーコントロールのコード

<UserControl x:Class="MvvmLight1.FolderDialog" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      xmlns:vm="clr-namespace:MvvmLight1" 
      xmlns:local="clr-namespace:MvvmLight1" 
      mc:Ignorable="d" d:DesignWidth="300" Height="186.916" > 
    <Grid> 
     <Grid.RowDefinitions> 
      <RowDefinition Height="90*"/> 
      <RowDefinition Height="97*"/> 
     </Grid.RowDefinitions> 
     <Grid> 
      <TextBox Text="{Binding SelectedPath}" /> 
     </Grid> 
     <Grid Grid.Row="1" > 
      <Button Command="vm:OpenFileDialogVM.OpenCommand" >Browse</Button> 
     </Grid> 

    </Grid> 
</UserControl> 

これまでのブラウズは機能しています。私の質問は、どのように私はこのコードを呼び出すことができますです。フォルダの選択後、私は私のリストビューにデータを入れることができるのですか?

private void Call(string selectedpath) 
     { 
      try 
      { 
       var allFiles = Directory.GetFiles(selectedpath, "*", SearchOption.AllDirectories); 

       foreach (var item in allFiles) 
       { 
        System.Console.WriteLine(item); 
        //code for populating listview 
       } 
      } 
      catch (System.Exception ex) 
      { 
       System.Console.WriteLine(ex.StackTrace); 
       throw ex; 
      } 
     } 

ありがとうございます。

あなたのビューモデルは、ディレクトリを選択したときに移入されたファイル名

public ObservableCollection<string> FileNames { get; } 
    = new ObservableCollection<string>(); 

ObservableCollectionを持っている必要があり

+0

注:のSystem.Windows.Formsのための参照を追加 –

+0

はい。 MVVMを使用してコードを呼び出す方法を教えてください。私はフォルダを選択した後にありがとう – classname13

+0

今私のIDEで再現。将来の参考として、質問を書く方法については[MCVE](https://stackoverflow.com/help/mcve)を参照してください(これはかなり良い仕事です)。 –

答えて

1
  • ファイルを公開可能なコレクションにします。
  • PropertyChangedイベントを発生させます。
  • ウィンドウのdatacontextをviewmodelに設定します。
  • xamlのviewmodelのプロパティにバインドします。

CS

using System; 
    using System.ComponentModel; 
    using System.IO; 
    using System.Windows; 
    using System.Windows.Input; 
    using System.Collections.ObjectModel; 

    namespace StackOverflow_PopulateListView 
    { 
     /// <summary> 
     /// Interaction logic for MainWindow.xaml 
     /// </summary> 
     public partial class MainWindow : Window 
     { 
      public MainWindow() 
      { 
       InitializeComponent(); 
       DataContext = new OpenFileDialogVM(); 
      } 
     } 

     public class OpenFileDialogVM : ViewModelBase 
     { 
      public static RelayCommand OpenCommand { get; set; } 
      private string _selectedPath = "Enter a Path"; 
      public string SelectedPath 
      { 
       get { return _selectedPath; } 
       set 
       { 
        _selectedPath = value; 
        OnPropertyChanged("SelectedPath"); 
       } 
      } 

      private ObservableCollection<string> _files = new ObservableCollection<string>() { "Tits", "balls", "ass", "tits" }; 
      public ObservableCollection<string> Files 
      { 
       get { return _files; } 
       set 
       { 
        _files = value; 
        OnPropertyChanged("Files"); 
       } 
      } 

      private ICommand _selectFileCommand; 
      public ICommand SelectFileCommand 
      { 
       get 
       { 
        return _selectFileCommand ?? (_selectFileCommand = new RelayCommand(() => Call(SelectedPath))); 
       } 
       protected set 
       { 
        _selectFileCommand = value; 
       } 
      } 

      public void Call(string selectedpath) 
      { 
       try 
       { 
        Files = new ObservableCollection<string>(Directory.GetFiles(selectedpath, "*", SearchOption.AllDirectories)); 
       } 
       catch (Exception ex) 
       { 
        Console.WriteLine(ex.StackTrace); 
        throw ex; 
       } 
      } 
     } 

     public class RelayCommand : ICommand 
     { 
      public Action Act { get; set; } 

      /// <summary> Occurs when the target of the Command should reevaluate whether or not the Command can be executed. </summary> 
      public event EventHandler CanExecuteChanged; 

      public RelayCommand(Action act) 
      { 
       Act = act; 
      } 

      /// <summary> Returns a bool indicating if the Command can be exectued with the given parameter </summary> 
      public bool CanExecute(object obj) 
      { 
       return true; 
      } 

      /// <summary> Send a ICommand.CanExecuteChanged </summary> 
      public void ChangeCanExecute() 
      { 
       object sender = this; 
       EventArgs eventArgs = null; 
       CanExecuteChanged(sender, eventArgs); 
      } 

      /// <summary> Invokes the execute Action </summary> 
      public void Execute(object obj) 
      { 
       Act(); 
      } 
     } 

     /// <summary> 
     /// Extremely generic ViewModelBase; for copy-pasting into almost any MVVM project 
     /// </summary> 
     public class ViewModelBase : INotifyPropertyChanged 
     { 
      public event PropertyChangedEventHandler PropertyChanged; 

      /// <summary> 
      /// Fires PropertyChangedEventHandler, for bindables 
      /// </summary> 
      protected virtual void OnPropertyChanged(string name) 
      { 
       PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name)); 
      } 

     } 
    } 

XAML

<Window x:Class="StackOverflow_PopulateListView.MainWindow" 
    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:StackOverflow_PopulateListView" 
    mc:Ignorable="d" 
    Title="MainWindow" Height="350" Width="525" 
    > 
    <Grid> 
     <Grid.RowDefinitions> 
      <RowDefinition Height="8*"/> 
      <RowDefinition Height="1*"/> 
      <RowDefinition Height="1*"/> 
     </Grid.RowDefinitions> 

     <ListView ItemsSource="{Binding Files}" Grid.Row="0"> 
      <ListView.ItemTemplate> 
       <DataTemplate> 
        <TextBlock Text="{Binding}"/> 
       </DataTemplate> 
      </ListView.ItemTemplate> 
     </ListView> 

     <TextBox Grid.Row="1" 
        Text="{Binding SelectedPath}" 
       /> 

     <Button Grid.Row="2" 
        Content="Call" 
        Command="{Binding SelectFileCommand}" 
       /> 

    </Grid> 
</Window> 
+0

私は「viewmodelのファイルプロパティにxaml listviewをデータバインドする」という問題を解決しました。これには、スタンドアロンのコンパイルに必要なものすべてが含まれます。がんばろう! –

+0

ありがとうございました。そして今、私はそれらのコードが何であるか、そしていつそれらを使うのかを調べる必要があります。どうもありがとうございました – classname13

1

var files = Directory.EnumerateFiles(selectedpath, "*", SearchOption.AllDirectories); 

FileNames.Clear(); 

foreach (var file in files) 
{ 
    FileNames.Add(file); 
} 

あなたは、そのコレクションにリストボックスのItemsSourceプロパティをバインドします:

<ListBox ItemsSource="{Binding FileNames}"/> 
+0

ありがとうございます。どのようにmvvmパターンを使ってそのコードをいつ呼び出すのですか? – classname13

+0

「ディレクトリが選択されたとき」、つまりSelectedPathプロパティが変更されたとき、ありがとうございます。 – Clemens

関連する問題