【问题标题】:GetBindingExpression returns null at the second time it is calledGetBindingExpression 在第二次调用时返回 null
【发布时间】:2014-02-19 05:49:30
【问题描述】:

当在 ComboBox SelectedValue 属性上调用函数时,我发现 GetBindingExpression() 的一个奇怪行为。

它在第一次调用时工作正常,但在返回的 BindingExpression 上调用 UpdateTarget() 后,此 BindingExpression 似乎已从属性中删除。下一次 GetBindingExpression() 从属性返回 null。

BindingExpression exp;

// call it first time, returns an expression, and UpdateTarget success.
exp = ((ComboBox)obj).GetBindingExpression(ComboBox.SelectedValueProperty);

// call UpdateTarget
if (exp != null) exp.UpdateTarget();

// call it the second time, and now it returns null!
exp = ((ComboBox)obj).GetBindingExpression(ComboBox.SelectedValueProperty);

if (exp != null) exp.UpdateTarget();

如果我删除对 UpdateTarget() 的调用,那么下一个 GetBindingingExpression() 仍会返回一个有效的 BindingExpression。

CheckBox 的 IsChecked 属性不会发生此类问题。它总是与 CheckBox 的 IsChecked 属性一起正常工作。

XAML 如下所示:

  <Style TargetType="{x:Type ComboBox}" x:Key="GainComboBoxStyle_0x00000022">
     <Setter Property="Height" Value="20" />
     <Setter Property="MaxWidth" Value="80" />
     <Setter Property="FontFamily" Value="Calibri"/>
     <Setter Property="FontSize" Value="15"/>
     <Setter Property="FontWeight" Value="UltraBold"/>
     <Setter Property="Tag" Value="{StaticResource moduleGain_0x00000022}" />
     <Setter Property="Visibility" Value="{Binding Mode=OneWay, Converter={StaticResource getVisibilityOfGainConverter}}"/>

     <Style.Triggers>
        <DataTrigger Binding="{Binding Mode=OneWay, Converter={StaticResource isShowingGain}}" Value="True">
           <Setter Property="SelectedValue" Value="{Binding Path=., RelativeSource={RelativeSource Mode=Self}, Mode=OneWay, Converter={StaticResource getGainValue}}"/>
           <Setter Property="DisplayMemberPath" Value="Name" />
           <Setter Property="SelectedValuePath" Value="Name" />
           <Setter Property="IsSynchronizedWithCurrentItem" Value="False" />
           <Setter Property="ItemsSource" Value="{Binding Path=GainQ13Indices, Mode=OneTime}" />
        </DataTrigger>
     </Style.Triggers>
  </Style>

  <Style TargetType="{x:Type CheckBox}" x:Key="EnableCheckBoxStyle_0x00000010">
     <Setter Property="MaxWidth" Value="16"/>
     <Setter Property="Tag" Value="{StaticResource
                      moduleEnable_0x00000010}" />
     <Setter Property="Visibility" Value="{Binding Mode=OneWay, Converter={StaticResource getVisibilityOfEnableConverter}}"/>
     <Style.Triggers>
        <DataTrigger Binding="{Binding Mode=OneWay, Converter={StaticResource isShowingEnable}}" Value="True">
           <Setter Property="IsChecked" Value="{Binding Path=., RelativeSource={RelativeSource
                                          Mode=Self}, Mode=OneWay,
                                          Converter={StaticResource
                                          moduleEnableDisableConverter} }" />
        </DataTrigger>
     </Style.Triggers>
  </Style>

为什么 UpdateTarget() 会从 ComboBox 的 SelectedValue 属性中删除 BindingExpression?为什么它适用于 CheckBox 的 IsChecked 属性?

【问题讨论】:

  • 第二次仍然选择该项目吗?
  • 你能用 SelectedItem 代替 SelectedValue 试试吗?
  • 是的,它仍然被选中,你可以看到两个调用是并排的。第一个成功,第二个为空。我不能使用 SelectedItem,因为 BindingSource 仅用作输入并由未知数量的 ComboBoxes 共享以初始化它们的列表。绑定是一次性的,否则 ComboBox 会相互干扰。

标签: c# wpf binding


【解决方案1】:

确保您的 SelectedValue 设置为 GainQ13Indices 中包含的实际对象之一 - 看起来您可能在转换器中生成一个,这可能会导致绑定中断。应将 SelectedValue 设置为绑定到 ItemsSource 的集合中包含的内容。

我猜它适用于 IsChecked,因为它是一个布尔值,它是一种值类型,而您在 ComboBox 中使用的看起来像是一个引用类型(其中涉及更多的相等性检查)。

我以前遇到过这类问题,我已经养成了在视图模型中公开一个额外属性来表示每个公开列表的选定值的习惯,并避免尝试进行任何篡改与代码中的绑定。

例如(在视图模型中):

public ObservableCollection<Gain> GainQ13Indices { get; private set; }

public Gain SelectedGainQ13Indice { get; set; }

【讨论】:

  • 这是否意味着如果 UpdateTarget() 失败,那么 BindingExpression 会被删除?但似乎 UpdateTarget() 第一次成功了,因为我确实看到它在 GUI 上进行了相应更新。如果由于某些错误而将其删除,那么我可以重置它吗?我现在正在寻找重置它的方法。此外,GainQ13Indices 由多个(编译时未知数量)组合框共享。这就是为什么我使用 OneTime 绑定在开始时获取列表并使用 Converter 来决定每个 ComboBox 的 SelectedValue,否则它们会相互干扰。
  • 是的,第一次成功了,但是可能是因为做了一些无效的事情(比如将SelectedItem设置为“允许的项目”/ItemsSource中不包含的东西),直接赋值给了属性,就像您通过属性设置器设置它一样,并且不再通过绑定对其进行抽象 - 绑定被有效地替换为固定值。这仍然会在 GUI 中正常显示,但由于它是一个固定值且不再是绑定表达式,因此请求绑定表达式会返回 null。也许您的转换器 (getGainValue) 正在创建一个新对象?
猜你喜欢
  • 2023-03-28
  • 1970-01-01
  • 1970-01-01
  • 2010-11-17
  • 2023-03-21
  • 1970-01-01
  • 2012-03-29
  • 1970-01-01
  • 2010-11-29
相关资源
最近更新 更多