我有一个Windows Phone 8应用程序,我有一个名为RelayCommand
的{{1}}实例。我有一个DiscoverExpansionModulesCommand
属性绑定到Command
的按钮。首次加载应用时,会正确启用或禁用该按钮。但是,当在页面上并且我想要更改命令是否可以执行时,方法DiscoverExpansionModulesCommand
会正确触发并返回正确的true或false值,但按钮不会反映它。为什么按钮没有更新它的UI?我在http://social.msdn.microsoft.com/Forums/en-US/silverlightarchieve/thread/48a341e4-f512-4c33-befd-b614404b4920/
我的ViewModel:
CanExecuteDiscoverExpansionModulesCommand()
和XAML
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using GalaSoft.MvvmLight.Messaging;
using MAL.Portable.Commands;
using MAL.Portable.Message;
using MAL.Portable.Model;
using System;
using System.Collections.Generic;
using System.Windows.Input;
namespace MAL.Portable.ViewModel
{
public class SettingsViewModel : ViewModelBase
{
// Define an observable collection property that controls can bind to.
private List<Setting> settings;
private String controllerUrl;
private String controllerPort;
private String temperature;
private Wifi wifi;
private Boolean connected;
private Boolean checkingConnection;
public SettingsViewModel()
{
DiscoverExpansionModulesCommand = new RelayCommand(OnDiscoverExpansionModules, CanExecuteDiscoverExpansionModulesCommand);
Messenger.Default.Register<RetrieveSettingsMessage>
(
this, (action) => RetrievedListsMessage(action)
);
Messenger.Default.Send<GetSettingsMessage>(new GetSettingsMessage());
}
public ICommand DiscoverExpansionModulesCommand
{
get;
private set;
}
public String ConnectionStatus
{
get
{
if (checkingConnection)
return "checking";
else
return connected ? "connected" : "not connnected";
}
}
private Boolean CanExecuteDiscoverExpansionModulesCommand()
{
return connected;
}
private void OnDiscoverExpansionModules()
{
}
private void CheckConnection()
{
wifi = null;
if (!String.IsNullOrWhiteSpace(ControllerUrl) && !String.IsNullOrWhiteSpace(ControllerPort) && !checkingConnection)
{
checkingConnection = true;
wifi = new ReefAngelWifi(controllerUrl, controllerPort);
wifi.TestConnectionComplete += wifi_TestConnectionComplete;
wifi.RequestFail += wifi_RequestFail;
wifi.BeginTestConnection();
}
}
private void wifi_RequestFail(object sender, RequestExceptionEventArgs e)
{
connected = false;
checkingConnection = false;
RaisePropertyChanged("ConnectionStatus");
}
private void wifi_TestConnectionComplete(object sender, TestConnectionEventArgs e)
{
connected = e.TestSuccessful;
checkingConnection = false;
DiscoverExpansionModulesCommand.CanExecute(null);
RaisePropertyChanged("ConnectionStatus");
RaisePropertyChanged("DiscoverExpansionModulesCommand");
}
private object RetrievedListsMessage(RetrieveSettingsMessage action)
{
settings = action.Settings;
CheckConnection();
return null;
}
private String GetStringValue(String key)
{
if (settings == null) return String.Empty;
var item = settings.Find(x => x.Key == key);
if (item == null) return String.Empty;
else return item.Value;
}
private Boolean GetBooleanValue(String key)
{
if (settings == null) return false;
var item = settings.Find(x => x.Key == key);
if (item == null) return false;
else return Boolean.Parse(item.Value);
}
}
}
我正在使用MVVM Light可移植类库。
答案 0 :(得分:5)
当您在RelayCommand.RaiseCanExecuteChanged()
方法中评估的条件发生变化时,您需要致电CanExecute
。
修改强>
private void wifi_RequestFail(object sender, RequestExceptionEventArgs e)
{
connected = false;
checkingConnection = false;
RaisePropertyChanged("ConnectionStatus");
DiscoverExpansionModulesCommand.RaiseCanExecuteChanged();
}
private void wifi_TestConnectionComplete(object sender, TestConnectionEventArgs e)
{
connected = e.TestSuccessful;
checkingConnection = false;
DiscoverExpansionModulesCommand.CanExecute(null);
RaisePropertyChanged("ConnectionStatus");
RaisePropertyChanged("DiscoverExpansionModulesCommand");
DiscoverExpansionModulesCommand.RaiseCanExecuteChanged();
}
这不会导致循环,因为它只告诉RelayCommand重新执行指定的CanExecute方法。在您的情况下,这仅表示已读取属性CanExecuteDiscoverExpansionModulesCommand
。
答案 1 :(得分:1)
这似乎是一个跨线程问题。弄清楚如何在PCL中调用Dispatcher很棘手,但我在此处找到了它:Update UI thread from portable class library