public MainWindowVm(string directory,
                            VirtualCollectionSource <FileModel, FileViewModel> virtualSource)
        {
            Directory        = directory;
            VirtualSource    = virtualSource;
            FilterName       = new ReactivePropertySlim <string>().AddTo(Disposables);
            FilterExtension  = new ReactivePropertySlim <string>().AddTo(Disposables);
            CollectedSize    = new ReactivePropertySlim <int>().AddTo(Disposables);
            StagedSize       = new ReactivePropertySlim <int>().AddTo(Disposables);
            VirtualProxySize = new ReactivePropertySlim <int>().AddTo(Disposables);

            LowerFilterName      = FilterName.Select(x => x?.ToLower()).ToReadOnlyReactivePropertySlim().AddTo(Disposables);
            LowerFilterExtension = FilterExtension.Select(x => x?.ToLower()).ToReadOnlyReactivePropertySlim().AddTo(Disposables);

            // 仮想Cコンテナにフィルター関数を設定します。
            virtualSource.SetFilter( x =>  x.Filter(LowerFilterName.Value, LowerFilterExtension.Value)  );

            // 検索ボックスの入力からトリガしてフィルターを実行します。
            FilterName
            .Merge(FilterExtension)
            .Throttle(TimeSpan.FromMilliseconds(200), UIDispatcherScheduler.Default)
            .Subscribe(async _ => await VirtualSource.ResetCollection())
            .AddTo(Disposables);

            // 画面表示用に定期更新します
            Observable.Interval(TimeSpan.FromMilliseconds(100), UIDispatcherScheduler.Default)
            .Subscribe(_ =>
            {
                CollectedSize.Value    = VirtualSource.SourceSize;
                StagedSize.Value       = VirtualSource.Items.Count;
                VirtualProxySize.Value = VirtualSource.ProxySize;
            }).AddTo(Disposables);
        }
Example #2
0
        protected override async void OnStartup(StartupEventArgs e)
        {
            base.OnStartup(e);

            // ファイルを列挙するディレクトリをコマンドラインから取得します。
            // 指定がない場合は C:ドライブ直下を列挙します。
            var targetDirectory = _commandLineArgs.Any() ? Path.GetFullPath(_commandLineArgs[0]) : "C:\\";

            // データソースの作成-------------------------------------------------------
            var dataSource = new DataSource <FileModel>();

            // データの列挙に利用する IEnumeratorです。
            // Note: Directory.EnumerateFiles()とほぼ等価です。
            var dataSourceEnumerator = FileSystemEnumerator
                                       .EnumerateFiles(targetDirectory)
                                       .Select(x => new FileModel(x));

            // データソースの非同期読み取りを fire and forgetで開始します。
            _ = dataSource.StartRead(dataSourceEnumerator);

            // 仮想コンテナを作成--------------------------------------------------------
            var defaultCapacityCount = 50;// 仮想コンテナの初期サイズを50にします。

            var virtualSource = new VirtualCollectionSource <FileModel, FileViewModel>(
                dataSource.Items,
                x  =>  new FileViewModel(x),
                defaultCapacityCount,
                ImmediateScheduler.Instance);

            // 初期データの50個が読み込まれるまで待ちます。
            dataSource.BlockUntilRead(defaultCapacityCount);
            await virtualSource.ResetCollection();

            // ウィンドウの作成----------------------------------------------------------
            var vm     = new MainWindowVm(targetDirectory, virtualSource);
            var window = new MainWindow();

            window.DataContext = vm;
            window.Closed     += (_, _1) =>
            {
                vm.Dispose();
                virtualSource.Dispose();
                dataSource.Dispose();
            };
            window.Show();
        }