public void Task_02_PropertyChange_01_Normal()
        {
            CreateViewModel <ViewModel>(out var vm);

            ValueChangedArgs <string> nameArgs = null;
            var dName = vm.HookChange(v => v.Name, (_, e) => nameArgs = e);

            ValueChangedArgs <int> ageArgs = null;
            var dAge = vm.HookChange(v => v.Age, (_, e) => ageArgs = e);

            string property = null;
            var    dAll     = vm.HookChange((_, e) => property = e.PropertyName);

            vm.Name = null;
            Assert.That(nameArgs == null);

            vm.Name = "ABC";
            Assert.That(nameArgs != null);
            Assert.That(nameArgs.PropertyArgs.PropertyName == "Name");
            Assert.That(nameArgs.OldValue == null);
            Assert.That(nameArgs.NewValue == "ABC");
            Assert.That(nameArgs.ToString() == "Name: <null>=>ABC");
            Assert.That(vm.Name == "ABC");
            Assert.That(property == "Name");

            nameArgs = null;
            vm.Age   = 123;
            Assert.That(nameArgs == null);
            Assert.That(ageArgs.ToString() == "Age: 0=>123");
            Assert.That(property == "Age");

            dName.Dispose();
            dAge.Dispose();
            dAll.Dispose();
        }
        public void Task_03_Property_Interface()
        {
            CreateViewModel <ViewModel>(out var vm);
            var properties = vm.GetProperties();

            foreach (var p in properties)
            {
                Console.WriteLine($"{p.NameArgs.PropertyName}: {p.Type}, {p.Value}");
            }

            var property = properties.First(v => v.NameArgs.PropertyName == "Name");

            Assert.That(property.ToString() == $"{vm.GetType()} Name:{property.Value.ToStringEx()}");

            ValueChangedArgs <object> nameArgs = null;

            using (var dName = property.HookChange((_, e) => nameArgs = e))
            {
                property.Value = "ABC";

                Assert.That(nameArgs.PropertyArgs.PropertyName == "Name");
                Assert.That(nameArgs.OldValue == null);
                Assert.That((string)nameArgs.NewValue == "ABC");
                Assert.That(nameArgs.ToString() == "Name: <null>=>ABC");
            }
        }
            public void Task_02_ValueChanged()
            {
                var vm       = new TestViewModel();
                var property = new Property <TestViewModel, string>(vm, new PropertyChangedEventArgs("ABC"));

                ValueChangedArgs <string> args = null;

                void OnValueChanged(object sender, ValueChangedArgs <string> e)
                {
                    args = e;
                }

                using (property.HookChange(OnValueChanged))
                {
                    property.Value = "Value";
                    Assert.That(property.Value == "Value");
                    Assert.That(args.NewValue == "Value");
                    Assert.That(args.PropertyArgs == property.NameArgs);
                    Assert.That(args.ToString() == $"ABC: <null>=>Value");
                }
            }