首页 文章

接口上的只读属性可在PropertyGrid中编辑

提问于
浏览
1

我有一个带有一堆属性的接口,其中一些被定义为readonly,例如:

public interface IActivity {
  string Id { get; }
  bool IsEnabled { get; }
}

实现此接口的类具有公共 set 方法,供其他地方使用,但此接口的使用者不应该能够设置这些属性 . 我使用公共集合方法绑定到类,只要消费者应该关注的属性是可在网格内编辑的 .

我可以通过两种方式解决这个问题,首先是通过制作setter internal ,或者通过使用 [ReadOnly] 属性标记属性,但是这似乎不是"right",因为理论上其他东西可以实现我的控制之外的这个接口,那些据说只读属性然后可以通过属性网格更改 .

在将对象分配给属性网格时,我尝试显式转换为接口,但这也没有帮助:

propGrid.SelectedObject = (IActivity)obj;

有没有办法强制PropertyGrid控件尊重接口的 Contract ,而不是必须更改具体类?

2 回答

  • 1

    我通过创建一个完全匹配接口规范的包装类来解决这个问题:

    class ActivityWrapper : IActivity {
        private readonly IActivity _activity;
        public ActivityWrapper(IActivity activity) {
            _activity = activity;
        }
    
        public string Id
        {
            get { return _activity.Id; }
        }
        public bool IsEnabled
        {
            get { return _activity.IsEnabled; }
        }
    }
    

    在将对象暴露给属性网格时使用它:

    propGrid.SelectedObject = new ActivityWrapper((IActivity)obj);
    

    如果有一种不同的,更自动的方式来实现这一点,我仍然感兴趣,而不是维持另一个类 .

  • 1

    詹姆斯的回答是正确的 . 我将补充一点,如果您的IActivity实现了INotifyPropertyChanged,您必须以这样的方式路由事件:

    class ActivityWrapper : IActivity
    {
        private readonly IActivity _activity;
        public ActivityWrapper(IActivity activity)
        {
            _activity = activity;
            _activity.PropertyChanged += _activity_PropertyChanged;
        }
    
        public event PropertyChangedEventHandler PropertyChanged;
    
        void _activity_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (this.PropertyChanged != null)
                this.PropertyChanged(this, e);
        }
    
        public string Id
        {
            get { return _activity.Id; }
        }
        public bool IsEnabled
        {
            get { return _activity.IsEnabled; }
        }
    }
    

    我看到自动执行此操作的唯一方法是使用Reflection.Emit生成此包装器 .

相关问题