我想问一下如何使用MVVM模式填充listview我是mvvm模式的初学者,我从做事而不是阅读中学到更多。我在使用wpf之前完成了这个,但我使用的是代码。
我使用Mvvm Light。我想要的是浏览文件夹的位置,然后用其中的文件填充列表视图
到目前为止,我已经有了一个Browse文件夹
我有这个代码
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;
}
}
感谢您的时间。
答案 0 :(得分:2)
您的视图模型应该有ObservableCollection
个文件名
public ObservableCollection<string> FileNames { get; }
= new ObservableCollection<string>();
在选择目录时填充:
var files = Directory.EnumerateFiles(selectedpath, "*", SearchOption.AllDirectories);
FileNames.Clear();
foreach (var file in files)
{
FileNames.Add(file);
}
然后,您可以将ListBox的ItemsSource
属性绑定到该集合:
<ListBox ItemsSource="{Binding FileNames}"/>
答案 1 :(得分:2)
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));
}
}
}
<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>