如何将TabEventArgs中的ChildViewModel设为动态添加的TabItem的DataContext?
解决方案:给TabItem绑定ChildViewModel
我来帮你搞定这个问题!核心就是把从资源中获取的对象转换成MetroTabItem类型,直接赋值它的DataContext属性就行,同时还要注意资源实例共享的坑,具体步骤如下:
1. 修改OpenTab方法,设置DataContext
在你的OpenTab方法里,先把从Resources取出的object安全强转为MetroTabItem,然后将TabEventArgs里的ChildViewModel赋值给它的DataContext:
private void OpenTab(object sender, TabEventArgs e) { // 安全转换为MetroTabItem类型,避免空引用异常 if (WorkAreaTabCtrl.Resources[e.name] is mh.MetroTabItem tabItem) { // 将ChildViewModel绑定到TabItem的DataContext tabItem.DataContext = e.ChildViewModel; WorkAreaTabCtrl.Items.Add(tabItem); WorkAreaTabCtrl.SelectedItem = tabItem; } }
这样TabItem内部的myView1会自动继承这个DataContext(除非你给myView1手动设置了其他DataContext),视图里的绑定就能正常关联到你的ChildViewModel了。
2. 避免重复添加同一个TabItem实例(重要)
默认情况下,WPF的StaticResource是单例模式——每次从Resources里取的都是同一个MetroTabItem对象。如果多次调用OpenTab,重复添加同一个元素到TabControl会抛出异常(同一个UI元素不能同时存在于多个可视化树中)。
解决这个问题很简单,给资源里的MetroTabItem加上x:Shared="False"属性,让WPF每次请求资源时都创建一个新实例:
<mh:MetroTabItem CloseButtonEnabled="True" x:Key="{x:Static res:Resources.LBL_1}" Header="{x:Static res:Resources.LBL_1}" x:Shared="False"> <!-- 关键属性,每次获取新实例 --> <mh:MetroTabItem.Content> <path2view:myView1 x:Name="view1"/> </mh:MetroTabItem.Content> </mh:MetroTabItem>
3. 优化FocusTab方法(可选)
你也可以把FocusTab方法改成类型安全的写法,避免潜在的类型错误:
private void FocusTab(object sender, TabEventArgs e) { if (WorkAreaTabCtrl.Resources[e.name] is mh.MetroTabItem tabItem) { WorkAreaTabCtrl.SelectedItem = tabItem; } }
这样就完美解决你的问题啦!
内容的提问来源于stack exchange,提问作者Daniele Sartori
相关产品推荐
相关产品推荐

