【问题标题】:Why is my ComboBox SelectedItem null?为什么我的 ComboBox SelectedItem 为空?
【发布时间】:2011-11-08 03:15:04
【问题描述】:

我有一个 WPF/MVVM(使用 MVVM-Light)应用程序设置,其中包含一个位于 DataTemplate 内的 ComboBox。 ComboBox 的 XAML 如下所示:

<ComboBox x:Name="cbTeachers" 
          Grid.Column="1" 
          Style="{StaticResource ComboBox}" 
          ItemsSource="{Binding Teachers}" 
          Grid.Row="3" 
          DisplayMemberPath="Name" 
          SelectedValuePath="Id" 
          IsSynchronizedWithCurrentItem="False" 
          SelectedItem="{Binding Path=SelectedTeacher}">
     <i:Interaction.Triggers>
          <i:EventTrigger EventName="SelectionChanged">
               <i:InvokeCommandAction Command="{Binding TeacherSelectedCommand}"
                                      CommandParameter="{Binding SelectedItem, ElementName=cbTeachers}" />
          </i:EventTrigger>
     </i:Interaction.Triggers>
</ComboBox>

ItemsSource 的 Teachers 属性是一种称为 ObservableRangeCollection 的类型,它基于此处的代码:http://geekswithblogs.net/NewThingsILearned/archive/2008/01/16/have-worker-thread-update-observablecollection-that-is-bound-to-a.aspx,但它与标准的 ObservableCollection 非常相似。 SelectedTeacher 属性是在设置另一个属性时设置的,并且代码看起来与此非常相似:

this.SelectedTeacher = (from t in this.Teachers where t.Id == this.DataItem.Teacher.Id select t).Single();

我遇到的问题对我来说是零意义,一旦我设置了 SelectedTeacher,它就会被重置为 null。我可以单步调试调试器,看到 SelectedTeacher 有一个值,当我在属性的设置器上放置断点时,它肯定有这个值。但随后该属性再次被空值击中。我检查了调用堆栈,它显示唯一的前一行是外部代码(这是有道理的,因为我只在一个地方设置了该属性,并且它只被命中一次,正如预期的那样)。在调用堆栈窗口中展开“外部代码”选项会显示典型的 WPF 调用堆栈,其中可能包含 40 个方法,因此它绝对是 WPF 内部的,而不是我正在做的事情来使其重置。事实上,当我删除 SelectedItem="{Binding SelectedTeacher}" 时,该属性的设置器不会被第二次调用(因此它保留了它的值),但当然 ComboBox 也不会显示所选项目。我尝试在我的视图模型中实现 SelectedIndex 选项,但这也不起作用。 ComboBox 只是不会选择该项目。我可以更改 ComboBox 中的选定项,但初始设置不会。

有什么想法吗?根据我搜索的所有内容,它可能与我使用 DataTemplate 有关,但我必须这样做,因为该模板是父 ContentTemplateSelector 实现的一部分。

附带说明,我有多个属性绑定到此 DataTemplate 中的控件,这是唯一一个不起作用的属性。其他工作完美。我也尝试了带有和不带有“IsSynchronizedWithCurrentItem”标志的组合框,它没有任何区别。

【问题讨论】:

  • 为什么要绑定到 SelectedItem 和 SelectionChanged?
  • 目标是设置现有值(用户处于编辑模式),然后让他们在选择时更改值。 SelectionChanged 的​​命令实现只是将 SelectedTeacher 设置为等于他们选择的值。这实际上是非常基本的。

标签: wpf mvvm combobox mvvm-light


【解决方案1】:

你有没有试过删除到 EventTrigger 的东西,只是为了使用

SelectedItem="{Binding Path=SelectedTeacher, Mode=TwoWay}"

模式=双向?

我不清楚你想用 EventTrigger 实现什么?

【讨论】:

  • 我试过了,它仍然第二次设置 SelectedTeacher 属性为空值。这背后的目标是设置初始选定值(因为他们正在编辑现有项目),然后如果他们决定更改值,则使用 SelectionChanged 更新 SelectedTeacher 值。
  • 知道了!我从 ComboBox 中删除了该命令,并在 ComboBox 声明的末尾更改了其他一些内容,因此它看起来像这样: DisplayMemberPath="Name" IsSynchronizedWithCurrentItem="True" SelectedValue="{Binding Path=SelectedTeacher, Mode=TwoWay} ”。它看起来像是删除命令、更改为 SelectedValue(而不是 Item)和删除 SelectedValuePath 选项的组合。感谢您带领我朝着正确的方向前进!
  • 好吧,我几乎已经有了上面的结果,但事实证明它选择了 a 值,但不是正确的值。当我将“IsSynchronizedWithCurrentItem”设置为 false 时,它​​开始按预期工作。 WPF 确实有时会让事情变得混乱。将来还有其他人!
猜你喜欢
  • 2021-10-13
  • 2013-01-22
  • 1970-01-01
  • 2019-06-18
  • 2013-11-11
  • 2012-02-20
  • 1970-01-01
  • 1970-01-01
  • 2010-10-05
相关资源
最近更新 更多