Example #1
0
        /// <summary>
        /// Initializes a new instance of the <see cref="T:TabViewModel"/> class.
        /// </summary>
        public TabViewModel(MainViewModel mainViewModel)
        {
            if (mainViewModel == null)
            {
                throw new ArgumentNullException("mainViewModel");
            }
            this.MainViewModel = mainViewModel;

            React.To(() => mainViewModel.ActiveTab == this)
            .Set(() => IsActive);

            React.To(() => IsActive)
            .Switch(true, Brushes.Orange, Brushes.Gray)
            .Set(() => HeaderBackgroundColor);

            React.To(() => IsActive ? Header + " [active]" : Header)
            .Set(() => ExtendedHeader);

            //TODO: allow tracked expressions in switch method
            //(maybe make another method - ReactiveSwitch not to confuse).
            //Most of the time reactive behaviour would be expected, though.

            //React.To(() => IsActive)
            //    .Switch(true, () => Header + " [active]", () => Header)
            //    .Set(() => ExtendedHeader);
        }
Example #2
0
        public void TrackedCollectionOfCollections_DoesNotPopulateInnerCollectionItemChanges()
        {
            CollectionOfCollectionsObject = new CollectionOfCollections();
            var inner = new ObservableCollection <Person>();
            int age   = -1;

            CollectionOfCollectionsObject.DeepCollection.Add(inner);
            React.To(() => CollectionOfCollectionsObject.DeepCollection
                     .TrackItems().First().FirstOrDefault())
            .Where(p => p != null).Set(p => age = p.Age);

            var person = new Person()
            {
                Age = 10
            };

            inner.Add(person);

            age.Should().Be(10, "as person has been added to the inner collection, its Count has changed. " +
                            "Expression should be reevaluated.");

            person.Age = 20;
            age.Should().Be(10, "person is located in the inner collection and property changes of " +
                            "individual (inner) items should not be tracked.");
        }
Example #3
0
        /// <summary>
        /// Initializes a new instance of the <see cref="T:PlaceholderTab"/> class.
        /// </summary>
        public PlaceholderTab(MainViewModel mainViewModel)
            : base(mainViewModel)
        {
            //Autonumbering of placeholder tabs in format "Placeholder 1/4", etc.
            int currentCount = mainViewModel.Tabs.Count(tab => tab is PlaceholderTab) + 1;

            React.To(() => mainViewModel.Tabs.Count(tab => tab is PlaceholderTab))
            .Set(totalCount => this.Header = string.Format("Placeholder {0}/{1}", currentCount, totalCount));
        }
Example #4
0
        static Settings()
        {
            current = new Settings();
            var local = current;

            local.DecimalPlaces = 1;

            React.To(() => current.DecimalPlaces)
            .Set(places => local.NumberFormat = string.Format("{{0:f{0}}}", places));
        }
Example #5
0
        /// <summary>
        /// Initializes a new instance of the <see cref="T:PeopleViewModel"/> class.
        /// </summary>
        public PeopleViewModel(MainViewModel mainViewModel)
            : base(mainViewModel)
        {
            this.Header           = "People";
            this.AddPersonCommand = new RelayCommand(AddPerson);

            actors = new ObservableCollection <PersonViewModel>();
            actors.Add(new PersonViewModel(this)
            {
                Age = 54, Name = "Kevin Spacey"
            });
            actors.Add(new PersonViewModel(this)
            {
                Age = 32, Name = "Joseph Gordon-Levitt"
            });
            actors.Add(new PersonViewModel(this)
            {
                Age = 61, Name = "Mickey Rourke"
            });

            filmDirectors = new ObservableCollection <PersonViewModel>();
            filmDirectors.Add(new PersonViewModel(this)
            {
                Age = 54, Name = "Frank Darabont"
            });
            filmDirectors.Add(new PersonViewModel(this)
            {
                Age = 52, Name = "Peter Jackson"
            });
            filmDirectors.Add(new PersonViewModel(this)
            {
                Age = 50, Name = "Quentin Tarantino"
            });

            React.To(() => IsViewingActors ? actors : filmDirectors)
            .Set(() => People);

            React.To(() => People.TrackItems(p => p.Age))
            .Where(people => people.Any())
            .Select(people => people.Average(p => p.Age))
            .SetAndNotify(() => AverageAge);

            var settings = Settings.Current;

            React.To(() => string.Format("Average age:" + settings.NumberFormat, AverageAge))
            .SetAndNotify(() => AverageAgeString);
        }
Example #6
0
        public void TrackedCollection_RaisesNotificationsForIndividualItems()
        {
            People = new ObservableCollection <Person>();
            int age = -1;

            React.To(() => People.TrackItems())
            .Where(c => c.Any())
            .Set(c => age = c.First().Age);

            var person = new Person()
            {
                Age = 20
            };

            People.Add(person);
            person.Age = 30;

            age.Should().Be(30, "age has been changed and items ought to be tracked");
        }
Example #7
0
        /// <summary>
        /// Initializes a new instance of the <see cref="T:MainWindowVM"/> class.
        /// </summary>
        public MainWindowVM()
        {
            this.Logger = new InMemoryLogger();

            OperationPanelVM adultPanel     = new AdultPanelVM(this.Logger);
            OperationPanelVM youngsterPanel = new YoungsterPanelVM(this.Logger);

            personProperty = this.Create(() => Person, new Person());
            React.To(() => 18 - Person.Age).Where(age => age > 0).Set(age => YearsBelow18 = age);
            React.To(() => 70 - Person.Age).SetAndNotify(() => YearsLeftToRetirement);

            //One can use Select() to convert the value stream and then call SetAndNotify()
            //with the target property as an argument. Thus, still no need for manual INPC event raising.
            //React.To(() => Person.Age >= 18).Select(isAdult => isAdult ? adultPanel : youngsterPanel).
            //      SetAndNotify(() => OperationPanel);

            //The same result can be obtained by using the Switch extension method.
            React.To(() => Person.Age).Switch(age => age >= 18, adultPanel, youngsterPanel).
            SetAndNotify(() => OperationPanel);
        }
        public CyclicAccess_InnerModel(CyclicAccess_OuterModel outerModel)
        {
            this.OuterModel = outerModel;

            React.To(() => this.Age - OuterModel.AverageAge)
            .Select(diff =>
            {
                if (diff > 0)
                {
                    return(new AnyReferenceType(-90.0));
                }
                else if (diff == 0)
                {
                    return(new AnyReferenceType(0.0));
                }
                else
                {
                    return(new AnyReferenceType(90.0));
                }
            })
            .Set(() => ArrowIndicatorRotation);
        }
Example #9
0
        public NotificationsSwallowed_InnerModel(NotificationsSwallowed_OuterModel outerModel)
        {
            this.OuterModel = outerModel;

            React.To(() => this.Age - OuterModel.AverageAge)
            .Select(diff =>
            {
                if (diff > 0)
                {
                    return(new AnyReferenceType(-90.0));
                }
                else if (diff == 0)
                {
                    return(new AnyReferenceType(0.0));
                }
                else
                {
                    return(new AnyReferenceType(90.0));
                }
            })
            .SetAndNotify(() => ArrowIndicatorRotation);
        }
        public CyclicAccess_OuterModel()
        {
            actors = new ObservableCollection <CyclicAccess_InnerModel>();
            actors.Add(new CyclicAccess_InnerModel(this)
            {
                Age = 54
            });
            actors.Add(new CyclicAccess_InnerModel(this)
            {
                Age = 32,
            });
            actors.Add(new CyclicAccess_InnerModel(this)
            {
                Age = 61
            });

            filmDirectors = new ObservableCollection <CyclicAccess_InnerModel>();
            filmDirectors.Add(new CyclicAccess_InnerModel(this)
            {
                Age = 54
            });
            filmDirectors.Add(new CyclicAccess_InnerModel(this)
            {
                Age = 52
            });
            filmDirectors.Add(new CyclicAccess_InnerModel(this)
            {
                Age = 50
            });

            React.To(() => IsViewingActors ? actors : filmDirectors)
            .Set(() => People);

            React.To(() => People.TrackItems())
            .Where(people => people.Any())
            .Select(people => people.Average(p => p.Age))
            .SetAndNotify(() => AverageAge);
        }
Example #11
0
        public void NonTrackedCollectionOfCollections_DoesNotPopulateEvenOuterCollectionItemChanges()
        {
            CollectionOfCollectionsObject = new CollectionOfCollections();
            var inner = new ObservableCollection <Person>();
            int age   = -1;

            CollectionOfCollectionsObject.DeepCollection.Add(inner);
            React.To(() => CollectionOfCollectionsObject.DeepCollection.First().FirstOrDefault()).
            Where(p => p != null).Set(p => age = p.Age);

            var person = new Person()
            {
                Age = 10
            };

            inner.Add(person);

            age.Should().Be(-1, "item tracking is off. Even items of the outer collection " +
                            "should not be listened to.");

            person.Age = 20;
            age.Should().Be(-1, "item tracking is off");
        }
Example #12
0
        public PersonViewModel(PeopleViewModel peopleViewModel)
        {
            if (peopleViewModel == null)
            {
                throw new ArgumentNullException("peopleViewModel");
            }

            this.PeopleViewModel = peopleViewModel;

            React.To(() => this.Age - PeopleViewModel.AverageAge)
            .Select(diff =>
            {
                if (diff > 0)
                {
                    return("above average");
                }
                else if (diff == 0)
                {
                    return("exact average");
                }
                else
                {
                    return("below average");
                }
            })
            .SetAndNotify(() => ComparedToAverageAge);

            //TODO: SetAndNotify usually has no equality check on the new value.
            //Put such logic in SetAndNotify itself.
            React.To(() => this.Age - PeopleViewModel.AverageAge)
            .Select(diff =>
            {
                if (diff > 0)
                {
                    return(new RotateTransform(-90.0));
                }
                else if (diff == 0)
                {
                    return(new RotateTransform(0.0));
                }
                else
                {
                    return(new RotateTransform(90.0));
                }
            })
            .SetAndNotify(() => ArrowIndicatorRotation);

            React.To(() => this.Age - PeopleViewModel.AverageAge)
            .Select(diff =>
            {
                if (diff > 0)
                {
                    return(Brushes.Green);
                }
                else if (diff == 0)
                {
                    return(Brushes.Blue);
                }
                else
                {
                    return(Brushes.Red);
                }
            })
            .SetAndNotify(() => ArrowIndicatorColor);
        }