您的怀疑是正确的,这种方式破坏了 MVVM 模型并且无法使用可以简化您的工作的机制,例如Expression Blend SDK中可用的System.Windows.Interactivity中的触发器。
在 getter 中加载数据是自找麻烦。它将您的模型绑定到数据访问代码,通过在同一属性中混合不同的关注点,使测试更加困难并且代码更加复杂。此外,墨菲定律规定,在某些时候您只想设置属性而不从数据库重新加载。
更好的解决方案是在可以由命令或触发器调用的单独方法中提取数据加载代码。此方法将修改 Oc2 集合的内容或简单地将其替换为新集合。在任何情况下,属性设置器都会发出正确的通知,并且第二个组合将被更新。
以下示例来自fabien在类似 SO question 中的回答:
<ComboBox x:Name="fileComboBox" ItemsSource="{Binding FileList, Mode=TwoWay}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<i:InvokeCommandAction
Command="{Binding SelectionChangedCommand}"
CommandParameter="{Binding SelectedItems,
ElementName=fileComboBox}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</ComboBox>
大多数框架都支持这种设计。Caliburn.Micro提供 了在 UI 事件发生时将调用 ViewModel 方法的操作,以及避免编写触发器 XAML 和相应命令的快捷语法。它只是将事件连接到 ViewModel 方法。XAML 可以像这样简单:
<ComboBox x:Name="Oc1"
cal:Message.Attach="[Event SelectionChanged] =
[Action ReloadFor($this.SelectedItem)]" />
该$this
值是引用 ComboBox 本身的另一个速记。
如果您不想使用触发器,可以将组合的 SelectedItem 属性绑定到 ViewModel 属性,并在此属性更改时执行 Reload 方法,例如:
<ComboBox ... SelectedItem={Binding CurrentOC2,Mode=TwoWay} />