Caliburn.Micro 问题:PropertyChangedBase、BindableCollection 和 AutoMapper

Caliburn.Micro issue: PropertyChangedBase, BindableCollection and AutoMapper

我在 WPF 应用程序中使用 Caliburn.Micro MVVM 框架。 View 中有一个 DataGrid 绑定到 BindableCollection<SomeObjectStatus>.

public class SomeObjectStatus
        {
            public string Message { get; set; }
            public bool IsInitializing { get; set; }
        }

我需要以某种方式通知 UI SomeObjectStatus 的任何 属性 是否已更改。常见的方式是在每个属性中继承PropertyChangedBase并调用NotifyOfPropertyChange() setter:

public class SomeObjectStatus : PropertyChangedBase
    {
        private string _message;
        private bool _isInitializing;

        public string Message
        {
            get { return _message; }
            set
            {
                if (value == _message)
                    return;
                _message = value;
                NotifyOfPropertyChange();
            }
        }

        public bool IsInitializing
        {
            get { return _isInitializing; }
            set
            {
                if (value == _isInitializing)
                    return;
                _isInitializing = value;
                NotifyOfPropertyChange();
            }
        }
    }

但是 SomeObjectStatus 是一个 Model class,我不想用 NotifyOfPropertyChange() 之类的东西堵塞。 我可以创建具有相同属性的 SomeObjectStatus 的克隆 class,并专门为 ViewModel 实现 PropertyChangedBase,我们称之为 SomeObjectStatusWithNotify。但在这种情况下,我需要在发生更改时手动将 SomeObjectStatus 中的每个 属性 分配给 SomeObjectStatusWithNotify。在实际项目中,有太多属性无法手动分配。所以我需要以某种方式解决如何自动将值从 SomeObjectStatus 分配到 SomeObjectStatusWithNotify 具有相同名称的问题。感觉我在这里需要类似 AutoMapper 的功能。但是我需要为现有对象赋值,而不是像 AutoMapper 那样创建一个新对象。或者也许有一种优雅的方法可以从常规 class?

创建 PropertyChangedBase

如果您使用 Map():

的正确重载,AutoMapper 可以为现有对象赋值
[TestClass]
public class C
{
    [TestMethod]
    public void M()
    {
        Mapper.CreateMap<SomeObject, SomeOtherObject>();

        SomeObject source =  new SomeObject {Name = "An Object"};
        SomeOtherObject target = new SomeOtherObject {Id = 123};

        Mapper.Map(source, target);

        Assert.AreEqual(123, target.Id);
        Assert.AreEqual("An Object", target.Name);
    }

    private class SomeOtherObject
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }

    private class SomeObject
    {
        public string Name { get; set; }
    }
}