【发布时间】:2020-07-27 08:11:00
【问题描述】:
我的 .net Core 3.1 WPF 应用程序中有一个行为,它在视图显示后调用 ViewModel 中的命令。
public class LoadedBehavior
{
public static DependencyProperty LoadedCommandProperty
= DependencyProperty.RegisterAttached(
"LoadedCommand",
typeof(ICommand),
typeof(LoadedBehavior),
new PropertyMetadata(null, OnLoadedCommandChanged));
private static void OnLoadedCommandChanged
(DependencyObject depObj, DependencyPropertyChangedEventArgs e)
{
if (depObj is FrameworkElement frameworkElement && e.NewValue is ICommand)
{
frameworkElement.Loaded
+= (o, args) => { (e.NewValue as ICommand)?.Execute(null); };
}
}
public static ICommand GetLoadedCommand(DependencyObject depObj)
{
return (ICommand)depObj.GetValue(LoadedCommandProperty);
}
public static void SetLoadedCommand(
DependencyObject depObj,
ICommand value)
{
depObj.SetValue(LoadedCommandProperty, value);
}
}
此行为附加在视图内:
behaviors:LoadedBehavior.LoadedCommand="{Binding LoadedCommand}"
我正在使用 Prisms RegionManager 将我的视图注入视图内的特定区域。当我现在尝试注入新视图时,会再次调用从旧视图加载的命令。这似乎来自行为。
为了更好地理解,这里也是被调用以在特定区域内显示新视图的代码
public class NavigationService
{
private readonly IServiceLocator _serviceLocator;
private readonly IRegionManager _regionManager;
public NavigationService(IServiceLocator serviceLocator, IRegionManager regionManager)
{
_serviceLocator = serviceLocator;
_regionManager = regionManager;
}
public void Navigate(string regionName, object view)
{
RemoveAllViews(regionName);
_regionManager.AddToRegion(regionName, view);
}
public void Navigate<T>(string regionName) where T : FrameworkElement
{
var view = _serviceLocator.GetInstance<T>();
Navigate(regionName, view);
}
public void RemoveAllViews(string regionName)
{
_regionManager.Regions[regionName].RemoveAll();
}
}
谁能告诉我,我在这里做错了什么?还是这种行为不可行?
编辑
发布后,我发现了问题:加载的命令被多次调用。这似乎是由于该视图的内容发生更改而引起的。所以每次我添加一个新视图时,父视图都会调用它的加载事件。有没有办法只在视图显示后运行命令?
【问题讨论】:
-
如果是“旧”视图模型的命令,那么这可能仍然是视图的数据上下文。我一般不是棱镜的粉丝,因为它很复杂。对于区域和区域经理尤其如此。 99% 的情况下,任何初始化逻辑都应该放在视图模型中。
-
嗯,Prism 对我正在编写的所有应用程序都非常有效,而且我从来没有遇到过这样奇怪的问题。所以我认为我在这里做错了什么。我添加了当我想在区域内显示新视图时调用的代码。也许这有帮助