【发布时间】:2018-03-11 19:57:11
【问题描述】:
我有一个 WPF Mvvm-Light 应用程序,它使用选项卡控件向用户显示不同的视图。
问题:
我遇到的问题是,当程序第一次加载选项卡控件时显示为空。但是在本地调试时,这个问题永远不会发生。这个应用程序已经开发了一年多没有这个问题,突然间它开始发生了。见下图
黑客修复:
如果用户调整其窗口大小,选项卡控件中的内容会刷新并显示,并且在他们打开应用程序时问题不会再次出现。但是这个问题在第一次程序加载和第一次标签加载(同时发生)时发生 100% 的时间
详情:
这是我如何定义插入到选项卡控件中的视图
<DataTemplate DataType="{x:Type FtcViewModel:DashboardNavViewModel}">
<FtcView:DashboardNav />
</DataTemplate>
这是我的标签控件:
<TabControl Grid.Column="1" Grid.Row="3"
SelectedItem="{Binding CurrentViewModel}"
ItemsSource="{Binding OpenViewModelCollection}"
Style="{StaticResource TabControlStyle}"
ItemContainerStyle="{StaticResource TabItemStyle}" >
</TabControl>
然后在我的主窗口视图模型中,我将一个集合分配给选项卡控件,并默认将仪表板设置为第一个打开的选项卡(试图只包含相关代码,显然在 viewModel 文件中还有更多):
Public Property OpenViewModelCollection As ObservableCollection(Of ViewModelHelper)
Get
Return Me._OpenViewModelCollection
End Get
Set(value As ObservableCollection(Of ViewModelHelper))
If _OpenViewModelCollection Is value Then
Return
End If
_OpenViewModelCollection = value
RaisePropertyChanged(OpenViewModelCollectionPropertyName)
End Set
End Property
Public Property CurrentViewModel As ViewModelHelper
Get
Return Me._CurrentViewModel
End Get
Set(value As ViewModelHelper)
If _CurrentViewModel Is value Then
Return
End If
''if change of viewmodel is not from OpenTabViewModelCommandExecute method
If FlagOpening = False AndAlso value IsNot Nothing Then
If _CurrentViewModel IsNot Nothing Then
_CurrentViewModel.HandleNavigation(True)
End If
''Mark NavService target VM
_NavService.TargetViewModelKey = value.vmKey
''evaluate if naviagtion has been canceled
If _NavService.bCanNavigate = False Then
_NavService.bCanNavigate = True
Exit Property
End If
End If
''if navigation not canceled, finish assigning new view model
_CurrentViewModel = value
RaisePropertyChanged(CurrentViewModelPropertyName)
If _CurrentViewModel IsNot Nothing Then
_CurrentViewModel.RefreshModel()
End If
End Set
End Property
...
'' THIS CODE IS FROM THE CONSTRUCTOR OF THE VIEW MODEL CLASS
OpenViewModelCollection.Add(_Locator.DashboardHome_VM)
CurrentViewModel = OpenViewModelCollection(0)
问题
谁能帮我弄清楚为什么会发生这种情况,或者建议一种在第一次加载应用程序后刷新 UI 的方法。
提前致谢
更新 1 - 2017 年 10 月 4 日
我已经能够在我的开发机器上重现这个问题。当 UI 为空白时,您可以看到 XAML diagnostics tools 不显示。下图显示了正在调试的同一个应用程序,但没有 XAML 工具框的应用程序是缺少 ui 元素的应用程序。
以下内容未在我的自定义选项卡控件样式中呈现:
<ScrollViewer VerticalScrollBarVisibility="Disabled" HorizontalScrollBarVisibility="Auto" >
<ContentPresenter x:Name="PART_SelectedContentHost" ContentSource="SelectedContent" Margin="{TemplateBinding Padding}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</ScrollViewer>
编辑 2017 年 10 月 11 日
我在 ViewModel 中的 xaml 和代码中都设置了断点。我可以确认 ViewModel 数据已正确初始化并分配给可观察对象。我还在 tabItemTemplate 中插入了“测试”文本块,以确认哪个部分没有显示。现在我有一个可怕的黑客在应用程序启动时从代码调整窗口大小,虽然它有效,但我仍然想弄清楚发生了什么。
【问题讨论】:
-
我只能给你一些一般性的建议。您可以使用 WPF Snoop (snoopwpf.codeplex.com) 调试 WPF 应用程序。即使问题发生在发布版本的客户端机器上。如果您有任何绑定错误,我还建议您删除 - 您会在输出窗口中找到它们。记录它们也可能有很大帮助(请参阅:github.com/bblanchon/WpfBindingErrors)。
-
@swiszcz 谢谢,我已经确认所有绑定错误都已删除。 snoop 太旧了,它不适用于我的应用程序。没有变化
-
另一个提示:在 .NET 3.5 前后,WPF 中存在一个错误,有时某些样式在第一次使用时未应用。您只需使用 ContentPresenter 两次即可检查是否是这种情况。
-
在 windows 构造函数中调用 InvalidateVisual() 不能解决这个问题吗?
-
看起来像这个问题,stackoverflow.com/a/21165350/495455 - 我认为根本原因与消息泵过滤器和 Got and Lost 焦点有关,请在此处查看这个奇怪的案例 stackoverflow.com/q/10526118/495455(参见类似的 WPF 案例)。
标签: wpf vb.net mvvm clickonce mvvm-light