在工作中,我们有一个使用Galasoft MVVM light框架制作的UWP应用程序。
在应用程序的屏幕之一上,有一个“设备”列表,其中包含一个用于修改该特定设备的按钮。 单击该按钮后,用户将导航到另一个页面,该页面具有带有4个选项卡的数据透视控件。此数据透视控件的项目来源是“视图”的集合。
其中一些选项卡还包含一些组合框,这些组合框具有键-值对列表以及绑定到它们的选定项属性。
最近,用户报告了一个问题,这些选项卡中的一个选项卡上的第一个下拉列表(组合框)没有选定的项目,而应该有。
我们开始测试该场景,直到一切开始一切正常,直到我开始使用Visual Studio Professional 2017(15.7.1)中提供的UWP模拟器进行测试,这真的很烦人,这要归功于每隔10分钟左右的BSOD使用。
无论如何,当将仿真器与“鼠标模式”用作选定的交互模式时,会出现问题。 调试后,我注意到从外部代码到ViewModel中的属性的setter的额外调用,该调用与所述组合框的selected item属性绑定,且值为null(也许是问题所在)。
我还注意到,打开选项卡页面后,这仅发生在我导航到的第一个选项卡的第一个组合框中。进一步导航后,无需再调用同一选项卡上的其他组合框或任何其他选项卡上的任何其他组合框。
当我使用“基本触摸模式”与应用程序进行交互时,问题似乎已经消失了。不会从外部代码调用设置器。
因此,在此之后,我开始认为该问题是由于多模式交互方案中的某些错误引起的。表面设备具有与其相连的键盘,该键盘具有触摸板。我已要求用户在断开键盘连接后重新测试该场景,他们回答后将更新问题。
更新:即使断开触摸板的连接,问题仍然存在于表面设备上。
因此,在这里我愿意公开提出想法,提出可能导致问题的原因和可能的解决方案。
下面给出的是带有硬编码值的示例,其行为方式相同。
XAML:
<ComboBox x:Name="IntervTypeComboBox" DisplayMemberPath="Label" <code></code> SelectedValuePath="Code"
Style="{StaticResource ComboStyle}"
ItemsSource="{Binding XYZ, Mode=TwoWay}"
ItemContainerStyle="{StaticResource ComboItemStyle}"
SelectedItem="{Binding SelectedXYZ, Mode=TwoWay}">
<ComboBox.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel Orientation="Vertical" Width="{Binding ActualWidth, ElementName=IntervTypeComboBox}"/>
</ItemsPanelTemplate>
</ComboBox.ItemsPanel>
</ComboBox>
C#:
public ObservableCollection<KeyValueModel> XYZ
{
get
{
return _xyz;
}
set
{
if (Set(() => XYZ, ref _xyz, value))
{
SelectedXYZ = XYZ.First();
}
}
}
public KeyValueModel SelectedXYZ
{
get { return _selectedXYZ; }
set
{
Set(() => SelectedXYZ, ref _selectedXYZ, value);
}
}
private void Constructor()
{
XYZ = new ObservableCollection<KeyValueModel> {
new KeyValueModel { Code="Default", Label="-- Sélectionner --"},
new KeyValueModel { Code="ABC", Label="ABC"},
new KeyValueModel { Code="DEF", Label="DEF"},
new KeyValueModel { Code="GHI", Label="GHI"}
};
SelectedXYZ = XYZ.FirstOrDefault(x => x.Code == "DEF");
}
我试图在执行Selected item属性的setter之前对值进行空检查,但是没有用。我尝试将项目-源的绑定模式从两种更改为一次性,也没有用。 然后,我尝试将所选项目的绑定方式从两种方式更改为一种方式,并使用选择更改事件来更新视图模型属性,这是一种不好的做法,没有任何区别。