public CreateProjectProgressViewModel(FlutnetAppSettings appSettings, FlutnetProjectSettings projectSettings, NewProjectViewModel screen = null) : base("newprj_progress", screen)
        {
            _appSettings     = appSettings;
            _projectSettings = projectSettings;

            Title                = "New Project";
            Description          = "The project will take some time to generate.\nWait until the procedure finish.\n";
            IsDescriptionVisible = false;

            NextText     = "Finish";
            BackVisible  = false;
            IsFinishPage = true;

            OutputLines = new ObservableCollection <string>();
            // Observe any changes in the observable collection.
            // Note that the property has no public setters, so we
            // assume the collection is mutated by using the Add(),
            // Delete(), Clear() and other similar methods.
            OutputLines
            // Convert the collection to a stream of chunks,
            // so we have IObservable<IChangeSet<TKey, TValue>>
            // type also known as the DynamicData monad.
            .ToObservableChangeSet()
            // Each time the collection changes, we get
            // all updated items at once.
            .ToCollection()
            // Aggregate all the elements in the collection
            // into a multi-line string.
            .Select(lines => string.Join(Environment.NewLine, lines))
            // Then, we convert the multi-line string to the
            // property a multi-line TextBox can bind.
            .ToProperty(this, x => x.Output, out _output, scheduler: RxApp.MainThreadScheduler);

            // Create the command that calls Flutnet CLI
            CreateProject = ReactiveCommand.CreateFromTask(async ct =>
            {
                NewProjectInArg arguments = BuildCommandLineArg();

                CommandLineCallResult callResult = await CommandLineTools.Call <NewProjectOutArg>(arguments, ct, line =>
                {
                    OutputLines.Add(line);
                });

                // This is not the proper way to change property values and raise property change notifications:
                // we should return a public object and subscribe to the command observable
                // so that we can use ReactiveUI framework methods such as ToProperty, BindTo etc.
                if (callResult.Canceled)
                {
                    IsCanceled = true;
                }
                else if (callResult.Failed)
                {
                    IsFailed = true;
                }
                else
                {
                    OutArg result = callResult.CommandResult;
                    if (!result.Success)
                    {
                        IsFailed = true;
                    }
                    else
                    {
                        IsCompletedSuccessfully = true;
                    }
                }
            });

            CreateProject.IsExecuting.ToProperty(this, x => x.IsInProgress, out _isInProgress);
            CreateProject.IsExecuting.BindTo(this, x => x.IsBusy);

            BrowseProject = ReactiveCommand.Create(
                execute: () => Launcher.OpenFolder(Path.Combine(projectSettings.Location, projectSettings.SolutionName)),
                canExecute: this.WhenAnyValue(t => t.IsCompletedSuccessfully));

            // Execute the command when the View is activated
            Activator = new ViewModelActivator();
            this.WhenActivated(disposables =>
            {
                CreateProject.Execute(Unit.Default).Subscribe().DisposeWith(disposables);
            });

            this.WhenAnyValue(t => t.IsInProgress, t => !t).BindTo(this, t => t.NextEnabled);
        }
예제 #2
0
 protected override void SetOutputs(AsyncCodeActivityContext ctx, object output)
 {
     OutArg.Set(ctx, output);
     SetOutputsHandler(ctx, output);
 }