2 回答
TA贡献1784条经验 获得超2个赞
如何解决?
在更新命令状态后调用此方法:
CommandManager.InvalidateRequerySuggested();
为什么不更新?
命令仅在这些一般事件发生时更新:
KeyUp
MouseUp
GotKeyboardFocus
LostKeyboardFocus
有关详细信息,请参阅此源代码:CommandDevice.cs
对于其他控件,它有更多的事件需要刷新:
长按时重复增加RepeatButton
DataGrid
...SinglePageViewer
...
您可以双击此链接CommandManager.InvalidateRequerySuggested()
的方法查看其他刷新命令状态的事件。
因此,如果您的更新不在这些事件中发生,您的命令状态将不会更新。
其他信息
您说在使用 Visual Studio 并使用断点进行调试时,代码似乎在CanExecute
RelayCommand.cs 的函数中永远卡在一个循环中。
这不是 for 的循环CanExecute
,而是活动窗口在应用程序和 Visual Studio 之间切换时的GotKeyboardFocus
and事件。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 关注
- 114 浏览
添加回答
举报