2 回答
TA貢獻1784條經驗 獲得超2個贊
如何解決?
在更新命令狀態后調用此方法:
CommandManager.InvalidateRequerySuggested();
為什么不更新?
命令僅在這些一般事件發生時更新:
KeyUpMouseUpGotKeyboardFocusLostKeyboardFocus
有關詳細信息,請參閱此源代碼:CommandDevice.cs
對于其他控件,它有更多的事件需要刷新:
長按時重復增加RepeatButton
DataGrid...SinglePageViewer...
您可以雙擊此鏈接CommandManager.InvalidateRequerySuggested()的方法查看其他刷新命令狀態的事件。
因此,如果您的更新不在這些事件中發生,您的命令狀態將不會更新。
其他信息
您說在使用 Visual Studio 并使用斷點進行調試時,代碼似乎在CanExecuteRelayCommand.cs 的函數中永遠卡在一個循環中。
這不是 for 的循環CanExecute,而是活動窗口在應用程序和 Visual Studio 之間切換時的GotKeyboardFocusand事件。LostKeyboardFocus
TA貢獻1776條經驗 獲得超12個贊
簡答
問題在于Lifestyle您的 ViewModel 必須設置為 aSingleton而不是 default Transient。
private static Container Bootstrap()
{
// Create the container as usual.
var container = new Container();
// Register your types, for instance:
// Register your windows and view models:
//container.Register<MainWindow>(Lifestyle.Singleton); //not needed
container.Register<MainWindowViewModel>(Lifestyle.Singleton);
container.Verify();
return container;
}
然后你可以通過簡單的方式啟動應用程序
private static void RunApplication(Container container)
{
try
{
var mainWindow = container.GetInstance<MainWindow>();
var app = new App();
app.InitializeComponent();
app.Run(mainWindow);
}
catch (Exception ex)
{
//Log the exception and exit
Debug.WriteLine(ex.Message);
}
}
完整代碼在github 上。
長答案 - TL; DR
當您調用container.Verifyin 時,Bootstrap您將創建一個實例MainWindowViewModel來驗證其實例化,并創建另一個實例來驗證MainWindow類。
順便說一句,您可以通過不驗證容器來解決您的問題!
所以第二個解決方案是
//container.Register<MainWindow>(); // => Lifestyle.Transient;
container.Register<MainWindowViewModel>(); // => Lifestyle.Transient;
//container.Verify();
現在,請注意您在c.tor中有Mediator訂閱。MainWindowViewModel
public static void Subscribe(string token, Action<object> callback)
{
if (!pl_dict.ContainsKey(token))
{
var list = new List<Action<object>>();
list.Add(callback);
pl_dict.Add(token, list);
}
else
{
bool found = false;
//foreach (var item in pl_dict[token])
// if (item.Method.ToString() == callback.Method.ToString())
// found = true;
if (!found)
pl_dict[token].Add(callback);
}
}
foreach循環——我只在上面評論過(它是解決你的問題的第三個替代選項) ——會讓你跳過對第二個正確的 ViewModel 方法的調用,并會讓你留下第一個錯誤的方法(記住Bootstrap驗證創建了它兩次)。如果你想要第四種替代解決方案,使用中介者模式IComponent的經典界面
public interface IComponent
{
void OnGo1Screen(object obj);
void OnGo2Screen(object obj);
}
public class MainWindowViewModel : BaseViewModel, IComponent
您還可以將訂閱移出 c.tor
public MainWindowViewModel()
{
// Add available pages and set page
PageViewModels.Add(new UserControl1ViewModel());
PageViewModels.Add(new UserControl2ViewModel());
CurrentPageViewModel = PageViewModels[0];
//Mediator.Subscribe("GoTo1Screen", OnGo1Screen);
//Mediator.Subscribe("GoTo2Screen", OnGo2Screen);
}
進入你的Program:
var context = mainWindow.DataContext as IComponent;
Mediator.Subscribe("GoTo1Screen", context.OnGo1Screen);
Mediator.Subscribe("GoTo2Screen", context.OnGo2Screen);
- 2 回答
- 0 關注
- 166 瀏覽
添加回答
舉報
