在我的程序的开始屏幕中,我显示(非交互式)UserControl DocumentView
的缩略图,以在类似Tile的UserControl LoadTileView
中显示不同的文档,用户可以在其上单击将文档加载到主视图中。此DocumentView
也用于主视图中,以图形方式表示和编辑所选文档。由于此DocumentView
图形较重,因此加载需要一些时间,这会导致巨大的启动时间,因为我在开始屏幕内显示DocumentView
的多个实例(例如,各种Tiles,用户可以选择要编辑的文档。
因此,我正在开发一种方法来保存属于每个DocumentView
的{{1}}实例的缓存图像,以便可以显示它而不是实际的LoadingTileView
我的程序下次启动。
我目前正在研究如何保存缓存图像。我的想法是让每个DocumentView
在加载后通过MVVM-Light LoadTileView
调用LoadingTileViewModel
并将RelayCommand
的实例传递给命令。我将DocumentView
放在DataTemplate中,以便我可以通过在DocumentView
中相应地设置CurrentDocumentViewModel
来替换它的缓存图像(以及相应的View)。
我找到了关于如何将LoadingTileView
传递给ViewModel (here)以及如何将UIElement
与参数(here)一起使用的说明。结合使用blender交互触发器触发ViewModel中的RelayCommand
,可以得到如下所示的简化代码。
此代码编译并运行,但ViewLoadedEventHandlerCommand
中的parameter
为ExecuteViewLoadedEventHandlerCommand(object parameter)
。我还尝试直接使用Null
,而不是DocumentView
,但ContentControl
仍为parameter
。
我不确定我在这里做错了什么,因为我在其他情况下使用了Null
和RelayCommand
这些,他们正确地工作了。也许有人可以发现我的错误?
LoadingTileView 的代码:
Interaction.Triggers
LoadingTileViewModel的代码:
<UserControl.Resources>
<DataTemplate DataType="{x:Type ViewModels:DocumentViewModel}">
<View:DocumentView/>
</DataTemplate>
</UserControl.Resources>
<i:Interaction.Triggers>
<i:EventTrigger EventName="Loaded">
<i:InvokeCommandAction Command="{Binding ViewLoadedEventHandlerCommand}"
CommandParameter="{Binding ElementName=DocumentViewInstance}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<Controls:Tile Command="{Binding LoadProgramCommand}">
<Viewbox>
<ContentControl x:Name="DocumentViewInstance" Content="{Binding CurrentDocumentViewModel}"/>
</Viewbox>
</Controls:Tile>
更新
Stacktrace,在第public LoadingTileViewModel()
{
...
ViewLoadedEventHandlerCommand = new RelayCommand<object>((obj)=>ExecuteViewLoadedEventHandlerCommand(obj));
...
}
public RelayCommand<object> ViewLoadedEventHandlerCommand { get; set; }
private void ExecuteViewLoadedEventHandlerCommand(object parameter) // object is NULL
{
UIElement toSave = (UIElement)parameter;
//OnViewLoaded();
}
行突破时:
UIElement toSave = (UIElement)parameter;
答案 0 :(得分:0)
在评论中你说someinput
到达命令。这意味着元素名称绑定要么完全失败要么迟到。
所以:要进行测试,请添加一个Button
i:InvokeCommandAction
但<i:EventTrigger EventName="Click">
Tile
,Loaded
这样可以测试以后的Binding是否有效。
调试时,请注意VS中的输出窗口。如果绑定失败,则应该有消息。
我的假设是问题出在[HttpPost]
控制之内。我猜你的Tile控件在public class HomeController
{
[HttpPost]
public ActionResult Method1 (object abc)
{
//blah
//blah
return blah
}
[HttpPost]
public ActionResult Method2 (object abc)
{
//blah
//blah
return blah
}
[HttpPost]
public ActionResult Method3 (object abc)
{
//blah
//blah
return blah
}
}
事件发生时还没有初始化它的子元素。
答案 1 :(得分:0)
事实证明,问题是Loaded
TileView
事件在加载DataTemplate内的DocumentView
之前触发了。我通过将DocumentViewModel
中的另一个命令附加到Loaded
的{{1}}事件中找到了这一点。之后我看到马库斯的答案,这基本上就是他的建议。
最后,我通过将DocumentView
事件的命令移动到DataTemplate来使我的代码工作。为此,我使用Loaded
绑定到其StackPanel
事件,以便我最终得到:
Loaded