【问题标题】:WPF share string between 2 viewmodels2个视图模型之间的WPF共享字符串
【发布时间】:2014-08-28 15:46:33
【问题描述】:

我是这个WPF世界的新手,我有以下情况:

我正在使用 VLC 和 Caliburn.Micro 开发与多媒体相关的应用程序,我遇到了一个问题,我需要将来自 MainViewModel 的变量 TotalTimeSettingsViewModel 上的 TextBox 共享.

这个变量恰好每秒都在变化,所以必须每秒通知一次。

MainViewModel -> string TotalTime

SettingsViewModel -> TextBox Time

我尝试过用事件来做,但我没有成功。

【问题讨论】:

  • 你能发布两个视图模型的代码吗?如果没有看到代码及其关系,这个问题是无法回答的。

标签: c# wpf mvvm viewmodel


【解决方案1】:

如果您将 SettingsViewModel 作为属性嵌套在 MainViewModel 中(例如 Settings),您可以像这样将 UI 元素绑定到它:

Text = "{Binding Path=Settings.TotalTime}"

如果 View 的 DataContext 设置为 MainViewModel 的实例

【讨论】:

    【解决方案2】:

    一般来说,这个问题的解决方案是两个视图模型在创建时(通常来自 IoC 容器)注入的单例信使。在您的场景中,SettingsViewModel 将订阅特定类型的消息,例如TotalTimeChangedMessage,而MainViewModel 将在TotalTime 更改时发送该类型的消息。该消息仅包含TotalTime 的当前值,例如:

    public sealed class TotalTimeChangedMessage
    {
        public string totalTime;
    
        public TotalTimeChangedMessage(string totalTime)
        {
            this.totalTime = totalTime;
        }
    
        public string TotalTime
        {
            get { return this.totalTime; }
        }
    }
    

    Caliburn.Micro 包含一个event aggregator,您可以使用它在视图模型之间以这种方式传递消息。你的MainViewModel 会这样发送消息:

    public class MainViewModel
    {
        private readonly IEventAggregator _eventAggregator;
    
        public MainViewModel(IEventAggregator eventAggregator)
        {
            _eventAggregator = eventAggregator;
        }
    
        public string TotalTime
        {
            set
            {
                this.totalTime = value;
                _eventAggregator.Publish(new TotalTimeChangedMessage(this.totalTime));
            }
        }
    }
    

    ..你的 SettingsViewModel 会这样处理它:

    public class SettingsViewModel: IHandle<TotalTimeChangedMessage>
    {
        private readonly IEventAggregator eventAggregator;
    
        public SettingsViewModel(IEventAggregator eventAggregator)
        {
            this.eventAggregator = eventAggregator;
            this.eventAggregator.Subscribe(this);
        }
    
        public void Handle(TotalTimeChangedMessage message)
        {
            // Use message.TotalTime as necessary
        }
    }
    

    【讨论】:

    • 所以基本上你是在使用事件聚合来通知视图模型属性发生了变化?为什么不简单地在父视图模型上听“PropertyChanged”事件呢?这基本上是拿大炮打水枪。
    • 问题中没有任何地方表明SettingsViewModelMainViewModel 的子代。并且不应为了获得单个 string 值而将其更改为子级 - 这会将对 MainViewModel 的依赖添加到 SettingsViewModel 中,并在它们之间引入紧密耦合。
    • 没错,SettingsViewModel 不是 MainViewModel 的子节点
    猜你喜欢
    • 1970-01-01
    • 2011-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-20
    相关资源
    最近更新 更多