Caliburn.Micro问题:PropertyChangedBase,BindableCollection和AutoMapper

时间:2015-12-22 22:31:13

标签: c# binding automapper caliburn.micro inotifypropertychanged

我在WPF应用程序中使用Caliburn.Micro MVVM框架。 视图中的DataGridBindableCollection<SomeObjectStatus>绑定。

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

我需要以某种方式通知UI,SomeObjectStatus的任何属性都被更改。常见的方法是在每个属性设置器中继承PropertyChangedBase和调用NotifyOfPropertyChange()

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

1 个答案:

答案 0 :(得分:1)

如果使用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; }
    }
}