View model for a command with fixed context that is required during command execution
Наследование: ViewModelBase
        public void ContextualCommandsCollection_HasCommands_ChangedOnCollectionChange()
        {
            // Setup
            var testSubject = new ContextualCommandsCollection();
            int hasCommandsChangedCounter = 0;
            ((INotifyPropertyChanged)testSubject).PropertyChanged += (o, e) =>
              {
                  if (e.PropertyName == "HasCommands")
                  {
                      hasCommandsChangedCounter++;
                  }
              };

            // Case 1: Add command
            var cmd1 = new ContextualCommandViewModel(this, new RelayCommand(() => { }));
            var cmd2 = new ContextualCommandViewModel(this, new RelayCommand(() => { }));
            // Act
            testSubject.Add(cmd1);
            testSubject.Add(cmd2);

            // Verify
            Assert.AreEqual(2, hasCommandsChangedCounter, "Adding a command should update HasCommands");

            // Case 2: Remove command
            // Act
            testSubject.Remove(cmd1);
            // Verify
            Assert.AreEqual(3, hasCommandsChangedCounter, "Adding a command should update HasCommands");

            // Case 3: Update command
            // Act
            testSubject[0] = cmd1;
            // Verify
            Assert.AreEqual(4, hasCommandsChangedCounter, "Adding a command should update HasCommands");
        }
 public void ContextualCommandViewModel_Ctor_NullArgChecks()
 {
     var command = new RelayCommand(() => { });
     ContextualCommandViewModel suppressAnalysisWarning;
     Exceptions.Expect<ArgumentNullException>(() =>
     {
         suppressAnalysisWarning = new ContextualCommandViewModel(null, command);
     });
 }
        public void ContextualCommandViewModel_CommandInvocation()
        {
            // Setup
            bool canExecute = false;
            bool executed = false;
            var realCommand = new RelayCommand<object>(
                (state) => 
                {
                    Assert.AreEqual(this, state);
                    executed = true;
                },
                (state) => 
                {
                    Assert.AreEqual(this, state);
                    return canExecute;
                });
            var testSubject = new ContextualCommandViewModel(this, realCommand);

            // Sanity
            Assert.IsNotNull(testSubject.Command);
            Assert.AreSame(realCommand, testSubject.InternalRealCommand);

            // Case 1: Can't execute
            canExecute = false;
            // Act
            Assert.IsFalse(testSubject.Command.CanExecute(null), "CanExecute wasn't called as expected");

            // Case 2: Can execute
            canExecute = true;

            // Act
            Assert.IsTrue(testSubject.Command.CanExecute(null), "CanExecute wasn't called as expected");

            // Case 3: Execute
            // Act
            testSubject.Command.Execute(null);
            Assert.IsTrue(executed, "Execute wasn't called as expected");
        }
        public void ContextualCommandViewModel_DisplayText()
        {
            // Setup
            var context = new object();
            var command = new RelayCommand(() => { });
            var testSubject = new ContextualCommandViewModel(context, command);

            using (var tracker = new PropertyChangedTracker(testSubject))
            {
                // Case 1: null
                // Act + Verify
                Assert.IsNull(testSubject.DisplayText, "Expected display text to return null when not set");

                // Case 2: static
                testSubject.DisplayText = "foobar9000";
                // Act + Verify
                Assert.AreEqual("foobar9000", testSubject.DisplayText, "Unexpected static display text");
                tracker.AssertPropertyChangedRaised(nameof(testSubject.DisplayText), 1);

                // Case 3: dynamic
                var funcInvoked = false;
                Func<object, string> func = x => 
                {
                    funcInvoked = true;
                    return "1234";
                };
                testSubject.SetDynamicDisplayText(func);
                // Act + Verify
                Assert.AreEqual("1234", testSubject.DisplayText, "Unexpected dynamic display text");
                Assert.IsTrue(funcInvoked, "Dynamic display text function was not invoked");
                tracker.AssertPropertyChangedRaised(nameof(testSubject.DisplayText), 2);
            }

            // Case 4: dynamic - null exception
            Exceptions.Expect<ArgumentNullException>(() => testSubject.SetDynamicDisplayText(null));
        }
        private void OnBindingFinished(ProjectInformation projectInformation, bool isFinishedSuccessfully)
        {
            this.IsBindingInProgress = false;
            this.host.VisualStateManager.ClearBoundProject();

            if (isFinishedSuccessfully)
            {
                this.host.VisualStateManager.SetBoundProject(projectInformation);

                var conflictsController = this.host.GetService<IRuleSetConflictsController>();
                conflictsController.AssertLocalServiceIsNotNull();

                if (conflictsController.CheckForConflicts())
                {
                    // In some cases we will end up navigating to the solution explorer, this will make sure that
                    // we're back in team explorer to view the conflicts
                    this.ServiceProvider.GetMefService<ITeamExplorerController>()?.ShowSonarQubePage();
                }
                else
                {
                    VsShellUtils.ActivateSolutionExplorer(this.ServiceProvider);
                }
            }
            else
            {
                IUserNotification notifications = this.host.ActiveSection?.UserNotifications;
                if (notifications != null)
                {
                    // Create a command with a fixed argument with the help of ContextualCommandViewModel that creates proxy command for the contextual (fixed) instance and the passed in ICommand that expects it
                    ICommand rebindCommand = new ContextualCommandViewModel(projectInformation, new RelayCommand<ProjectInformation>(this.OnBind, this.OnBindStatus)).Command;
                    notifications.ShowNotificationError(Strings.FailedToToBindSolution, NotificationIds.FailedToBindId, rebindCommand);
                }
            }
        }
        public void ContextualCommandViewModel_Icon()
        {
            // Setup
            var context = new object();
            var command = new RelayCommand(() => { });
            var testSubject = new ContextualCommandViewModel(context, command);

            using (var tracker = new PropertyChangedTracker(testSubject))
            {
                // Case 1: null
                // Act + Verify
                Assert.IsNull(testSubject.Icon, "Expected icon to return null when not set");

                // Case 2: static
                var staticIcon = new IconViewModel(null);
                testSubject.Icon = staticIcon;
                // Act + Verify
                Assert.AreSame(staticIcon, testSubject.Icon, "Unexpected static icon");
                tracker.AssertPropertyChangedRaised(nameof(testSubject.Icon), 1);

                // Case 3: dynamic
                var dynamicIcon = new IconViewModel(null);
                var funcInvoked = false;
                Func<object, IconViewModel> func = x => 
                {
                    funcInvoked = true;
                    return dynamicIcon;
                };
                testSubject.SetDynamicIcon(func);
                // Act + Verify
                Assert.AreSame(dynamicIcon, testSubject.Icon, "Unexpected dynamic icon");
                Assert.IsTrue(funcInvoked, "Dynamic icon function  was not invoked");
                tracker.AssertPropertyChangedRaised(nameof(testSubject.Icon), 2);
            }

            // Case 4: dynamic - null exception
            Exceptions.Expect<ArgumentNullException>(() => testSubject.SetDynamicIcon(null));
        }
        private void SetServerProjectsVMCommands(ServerViewModel serverVM)
        {
            foreach (ProjectViewModel projectVM in serverVM.Projects)
            {
                projectVM.Commands.Clear();

                if (this.Host.ActiveSection == null)
                {
                    // Don't add command (which will be disabled).
                    continue;
                }

                var bindContextCommand = new ContextualCommandViewModel(projectVM, this.Host.ActiveSection.BindCommand);
                bindContextCommand.SetDynamicDisplayText(x =>
                {
                    var ctx = x as ProjectViewModel;
                    Debug.Assert(ctx != null, "Unexpected fixed context for bind context command");
                    return ctx?.IsBound ?? false ? Strings.SyncButtonText : Strings.BindButtonText;
                });
                bindContextCommand.SetDynamicIcon(x =>
                {
                    var ctx = x as ProjectViewModel;
                    Debug.Assert(ctx != null, "Unexpected fixed context for bind context command");
                    return new IconViewModel(ctx?.IsBound ?? false ? KnownMonikers.Sync : KnownMonikers.Link);
                });

                var openProjectDashboardCommand = new ContextualCommandViewModel(projectVM, this.Host.ActiveSection.BrowseToProjectDashboardCommand)
                {
                    DisplayText = Strings.ViewInSonarQubeMenuItemDisplayText,
                    Tooltip = Strings.ViewInSonarQubeMenuItemTooltip,
                    Icon = new IconViewModel(KnownMonikers.OpenWebSite)
                };

                projectVM.Commands.Add(bindContextCommand);
                projectVM.Commands.Add(openProjectDashboardCommand);
            }
        }
        private void SetServerVMCommands(ServerViewModel serverVM)
        {
            serverVM.Commands.Clear();
            if (this.Host.ActiveSection == null)
            {
                // Don't add command (which will be disabled).
                return;
            }


            var refreshContextualCommand = new ContextualCommandViewModel(serverVM, this.Host.ActiveSection.RefreshCommand)
            {
                DisplayText = Strings.RefreshCommandDisplayText,
                Tooltip = Strings.RefreshCommandTooltip,
                Icon = new IconViewModel(KnownMonikers.Refresh)
            };

            var disconnectContextualCommand = new ContextualCommandViewModel(serverVM, this.Host.ActiveSection.DisconnectCommand)
            {
                DisplayText = Strings.DisconnectCommandDisplayText,
                Tooltip = Strings.DisconnectCommandTooltip,
                Icon = new IconViewModel(KnownMonikers.Disconnect)
            };

            var browseServerContextualCommand = new ContextualCommandViewModel(serverVM.Url.ToString(), this.Host.ActiveSection.BrowseToUrlCommand)
            {
                DisplayText = Strings.BrowseServerMenuItemDisplayText,
                Tooltip = Strings.BrowserServerMenuItemTooltip,
                Icon = new IconViewModel(KnownMonikers.OpenWebSite)
            };

            var toggleShowAllProjectsCommand = new ContextualCommandViewModel(serverVM, this.Host.ActiveSection.ToggleShowAllProjectsCommand)
            {
                Tooltip = Strings.ToggleShowAllProjectsCommandTooltip
            };
            toggleShowAllProjectsCommand.SetDynamicDisplayText(x =>
            {
                ServerViewModel ctx = x as ServerViewModel;
                Debug.Assert(ctx != null, "Unexpected fixed context for ToggleShowAllProjects context command");
                return ctx?.ShowAllProjects ?? false ? Strings.HideUnboundProjectsCommandText : Strings.ShowAllProjectsCommandText;
            });

            serverVM.Commands.Add(refreshContextualCommand);
            serverVM.Commands.Add(disconnectContextualCommand);
            serverVM.Commands.Add(browseServerContextualCommand);
            serverVM.Commands.Add(toggleShowAllProjectsCommand);
        }