【发布时间】:2017-05-25 02:18:51
【问题描述】:
我正在使用 MVVM 将 ComboBox 绑定到 ViewModel,我对重操作和选择更改几乎没有疑问。
我想在选中项发生变化时触发一些动作,我最初的做法是把逻辑放在选中项绑定的字段的setter中。
所以我的第一个问题是,这是一种好的做法还是有更好的方法?
这些操作在时间和资源上可能非常昂贵(需要通过网络服务检索数据)并且我不希望 UI 冻结,所以最近我开始从接收到的集合中发送消息在视图的代码隐藏中并异步调用 ViewModel 命令。
我只是在浪费时间还是有任何意义?
问题是,当我调试 UI 时,有时会冻结(它不会在发布时发生)。在这里和那里阅读我已经知道它可能与调试器有关,任何人都可以在 VS 2015 上确认这种行为吗?
附加信息
根据要求,我提供了一些示例。这是我的第一种方法:
(XAML)<ComboBox SelectedItem="{Binding SelectedField}"/>
(视图模型)
public class ViewModel
{
private MyObject _selectedField = null;
public MyObject SelectedField
{
get
{
return _selectedField;
}
set
{
if(_selectedField != value)
{
// Expensive action
_selectedField = value;
RaisePropertyChanged(() => SelectedField);
}
}
}
}
昂贵的操作会调用一些 Web 服务并且可能需要很长时间,这种设计是好的还是有更好的方法来实现这一点?
我的第二种方法是通过消息,如下例所示:
(ViewModel)
public class ViewModel
{
private MyObject _selectedField = null;
public MyObject SelectedField
{
get
{
return _selectedField;
}
set
{
if(_selectedField != value)
{
Messenger.Default.Send(new DoStuffMessage());
_selectedField = value;
RaisePropertyChanged(() => SelectedField);
}
}
}
private RelayCommand _doStuffCommand = null;
public ICommand DoStuffCommand
{
get
{
if (_doStuffCommand == null)
_doStuffCommand = new RelayCommand(async () => await DoStuff());
return _doStuffCommand;
}
}
private async Task DoStuff()
{
// Expensive action
}
}
(代码隐藏)
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
Messenger.Default.Register<DoStuffMessage>(this, DoStuffMessage_Handler);
}
private void DoStuffMessage_Handler(DoStuffMessage msg)
{
(DataContext as ViewModel).DoStuffCommand.Execute(null);
}
}
这种方法更好还是只是不好和无用?
【问题讨论】:
-
你的问题太宽泛了。您是否有一些可以发布的代码以及有关该代码的具体问题?
标签: c# wpf mvvm visual-studio-2015 combobox