代码之家  ›  专栏  ›  技术社区  ›  Kazuhiko Nakayama

Caliburn.Micro/属性未在IHandle/EventAggregator中更新

  •  0
  • Kazuhiko Nakayama  · 技术社区  · 7 年前

    1. 启动事件聚合器并发送消息。
    2. 在IHandle中捕获消息。

    I make a sample project in GitHub.

    你可以通过点击按钮来测试它。

    enter image description here

        public void PublishOnBackgroundThread(int flag) {
    
            Debug.WriteLine($"PublishOnBackgroundThread/{flag}");
            ix++;
            if( flag == 0)
            {
                _eventAggregator.PublishOnBackgroundThread(new HelloMessage(ix.ToString(), false));
            }
            else if( flag == 1)
            {
                _eventAggregator.PublishOnBackgroundThread(new HelloMessage(ix.ToString(), true));
            }
        }
    
        public void PublishOnCurrentThread(int flag)
        {
            Debug.WriteLine($"PublishOnCurrentThread/{flag}");
            ix++;
            if (flag == 0)
            {
                _eventAggregator.PublishOnCurrentThread(new HelloMessage(ix.ToString(), false));
            }
            else if (flag == 1)
            {
                _eventAggregator.PublishOnCurrentThread(new HelloMessage(ix.ToString(), true));
            }
        }
        public void PublishOnUIThread(int flag)
        {
            Debug.WriteLine($"PublishOnUIThread/{flag}");
            ix++;
            if (flag == 0)
            {
                _eventAggregator.PublishOnUIThread(new HelloMessage(ix.ToString(), false));
            }
            else if (flag == 1)
            {
                _eventAggregator.PublishOnUIThread(new HelloMessage(ix.ToString(), true));
            }
        }
        public void PublishOnUIThreadAsync(int flag)
        {
            Debug.WriteLine($"PublishOnUIThreadAsync/{flag}");
            ix++;
            if (flag == 0)
            {
                _eventAggregator.PublishOnUIThreadAsync(new HelloMessage(ix.ToString(), false));
            }
            else if (flag == 1)
            {
                _eventAggregator.PublishOnUIThreadAsync(new HelloMessage(ix.ToString(), true));
            }
        }
    
        public void Handle(HelloMessage message)
        {
    
            Debug.WriteLine($"Handle(HelloMessage message)/{message.UiAsync}/{message.msg}");
            if (message.UiAsync)
            {
                Execute.OnUIThreadAsync(() =>
                {
                    _myText = message.msg;
                    MyText = _myText;
    
                });
                /*Execute.OnUIThread(() =>
                {
                    _myText = message.msg;
                    MyText = _myText;
    
                });*/
            }
            else
            {
                _myText = message.msg;
                MyText = _myText;
            }
        }
    
        private int ix = 0;
        private String _myText = "Update Number at Here !";
        public String MyText
        {
            get { return _myText; }
            set
            {
                Debug.WriteLine($"this.Set(ref _myText, value);");
                this.Set(ref _myText, value);
            }
        }
    

    Nere是xaml。

            <StackPanel.Resources>
                <Style TargetType="{x:Type Button}">
                    <Setter Property="Margin" Value="5"/>
                </Style>
            </StackPanel.Resources>
    
            <TextBlock Text="{Binding MyText, Mode=TwoWay}" Margin="50" />
            <Button Content="PublishOnBackgroundThread" cal:Message.Attach="[Event Click]=[Action PublishOnBackgroundThread(0)]"/>
            <Button Content="PublishOnCurrentThread" cal:Message.Attach="[Event Click]=[Action PublishOnCurrentThread(0)]"/>
            <Button Content="PublishOnUIThread" cal:Message.Attach="[Event Click]=[Action PublishOnUIThread(0)]"/>
            <Button Content="PublishOnUIThreadAsync" cal:Message.Attach="[Event Click]=[Action PublishOnUIThreadAsync(0)]"/>
    
    
            <Button Content="PublishOnBackgroundThread + Execute.OnUIThreadAsync" cal:Message.Attach="[Event Click]=[Action PublishOnBackgroundThread(1)]"/>
            <Button Content="PublishOnCurrentThread + Execute.OnUIThreadAsync" cal:Message.Attach="[Event Click]=[Action PublishOnCurrentThread(1)]"/>
            <Button Content="PublishOnUIThread + Execute.OnUIThreadAsync" cal:Message.Attach="[Event Click]=[Action PublishOnUIThread(1)]"/>
            <Button Content="PublishOnUIThreadAsync + Execute.OnUIThreadAsync" cal:Message.Attach="[Event Click]=[Action PublishOnUIThreadAsync(1)]"/>
    

    StackOverFlow网页不喜欢长代码。 然后,我在打字。。。。。。。。

    2 回复  |  直到 7 年前
        1
  •  2
  •   Frenchy    7 年前

    不要初始化私有变量myText,而是在构造函数中初始化myText

        private readonly IEventAggregator _eventAggregator;
        public BaseViewModel()
        {
            MyText = "Update Number at Here !";
            _eventAggregator = IoC.Get<IEventAggregator>();
        }
    

    如果使用依赖注入,效果更好:

        private readonly IEventAggregator _eventAggregator;
        public BaseViewModel(IEventAggregator _eventAggregator)
        {
            MyText = "Update Number at Here !";
            this._eventAggregator = _eventAggregator;
        }
    

    然后声明属性:

    private String _myText;
    public String MyText
    {
        get { return _myText; }
        set
        {
            Debug.WriteLine($"this.Set(ref _myText, value);");
            this.Set(ref _myText, value); // or
            //_myText = value;
            //NotifyOfPropertyChange(() => MyText);
        }
    }
    

        public void Handle(HelloMessage message)
        {
            Debug.WriteLine($"Handle(HelloMessage message)/{message.UiAsync}/{message.msg}");
            if (message.UiAsync)
            {
                Execute.OnUIThreadAsync(() =>
                {
                    MyText = message.msg;
    
                });
                /*Execute.OnUIThread(() =>
                {
                    _myText = message.msg;
                    MyText = _myText;
    
                });*/
            }
            else
            {
                MyText = message.msg;
            }
        }
    

    不要更新私有变量myText,而只更新公共变量myText

    使用this.Set或注释中的两行是相同的。。它们都调用caliburn中的最终方法:

        /// <summary>
        /// Notifies subscribers of the property change.
        /// </summary>
        /// <param name="propertyName">Name of the property.</param>
        // Token: 0x060000BF RID: 191 RVA: 0x0000342C File Offset: 0x0000162C
        public virtual void NotifyOfPropertyChange([CallerMemberName] string propertyName = null)
        {
            if (this.IsNotifying && this.PropertyChanged != null)
            {
                this.OnUIThread(delegate
                {
                    this.OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
                });
            }
        }
    
        2
  •  0
  •   arcticwhite    7 年前

    在你的房子里 MyText ,在 set

    set {
        Debug.WriteLine($ "this.Set(ref _myText, value);");
        this.Set(ref _myText, value);
        NotifyOfPropertyChange(() => MyText);
    }
    

    还有里面 Handle NotifyOfPropertyChange(() => MyText); 因为您现在在更改values属性时调用它。