使用mvvm填充Listview

时间:2017-05-06 05:31:41

标签: c# wpf listview mvvm mvvm-light

我想问一下如何使用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;
            }
        }

感谢您的时间。

2 个答案:

答案 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)

  • 将文件设为公共可观察集合。
  • 举起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>