代码之家  ›  专栏  ›  技术社区  ›  Harald Coppoolse

使用组合的类中的MvvmLight

  •  1
  • Harald Coppoolse  · 技术社区  · 6 年前

    我有一个ViewModel,源于 MvvmLight.ViewModelBase 重用其他使用的组合:

    要在合成中重用的类的简化版本:

    class TimeFrameFactory
    {
        public DateTime SelectedTime {get; set;}
    
        public ITimeFrame CreateTimeFrame() {...}
    }
    
    class GraphFactory
    {
         public int GraphWidth {get; set;}
    
         public IGraph CreateGraph(ITimeframe timeframe) {...}
    }
    

    我的ViewModel从MvvmLight ViewModelBase派生,由以下两个部分组成:

    class MyViewModel : ViewModelBase
    {
        private readonly TimeFrameFactory timeFrameFactory = new TimeFrameFactory();
        private readonly GraphFactory graphFactory = new GraphFactory();
    
        private Graph graph;
    
        // standard MVVM light method to get/set a field:
        public Graph Graph
        {
            get => this.Graph;
            private set => base.Set(nameof(Graph), ref graph, value);
        }
    
        // this one doesn't compile:
        public DateTime SelectedTime 
        {
            get => this.timeFrameFactory.SelectedTime;
            set => base.Set(nameof(SelectedTime), ref timeFrameFactory.SelectedTime, value);
        }
    
        // this one doesn't compile:
        public int GraphWidth
        {
            get => this.timeFrameFactory.GraphWidth;
            set => base.Set(nameof(GraphWidth), ref timeFrameFactory.GraphWidth, value);
        }
    
        public void CreateGraph()
        {
            ITimeFrame timeFrame = this.timeFrameFactory.CreateTimeFrame();
            this.Graph = this.GraphFactory.CreateGraph(timeFrame);
        }
    }
    

    带有字段的Get/Set可以工作,但是如果要将属性转发给复合对象,则不能使用 base.Set

    set => base.Set(nameof(GraphWidth), ref timeFrameFactory.GraphWidth, value);
    

    属性上不允许ref。

        public int GraphWidth
        {
            get => this.timeFrameFactory.GraphWidth;
            set
            {
                base.RaisePropertyChanging(nameof(GraphWidh));
                base.Set(nameof(GraphWidth), ref timeFrameFactory.GraphWidth, value);
                base.RaisePropertyChanged(nameof(GraphWidh));
            }
        }
    

    如果你要在很多地方做这件事,那就太麻烦了。有没有一个简单的方法可以做到这一点,可能类似于 ObservableObject.Set ?

    0 回复  |  直到 6 年前
        1
  •  1
  •   GazTheDestroyer    6 年前

    好吧,基方法需要能够读取(用于比较)和写入传递的字段/属性,因此ref。

    由于不能通过引用传递属性,我认为您不得不编写另一个基方法

    public int GraphWidth
    {
        get => this.timeFrameFactory.GraphWidth;
        set => base.Set(nameof(GraphWidth), () => timeFrameFactory.GraphWidth, x => timeFrameFactory.GraphWith = x, value);
    }
    

    B) 通过 Expression<Func<T>> 包含属性并使用反射来提取属性并在基中获取/设置它(速度慢,但也可能提取名称)

    public int GraphWidth
    {
        get => this.timeFrameFactory.GraphWidth;
        set => base.Set(() => timeFrameFactory.GraphWidth, value);
    }