在应用ContentTemplate之前更改内容后,ContentControl上的绑定错误

时间:2017-07-25 18:04:47

标签: wpf xaml

我有一个令人讨厌的问题并不会导致问题,但它会不必要地产生大量的绑定错误。

我基本上已经解决了这个问题,即在ContentControl上设置内容会在应用新的ContentTemplate之前更改其内容的DataContext。由于新内容与旧ContentTemplate所期望的类型不同,因此它会从旧的ContentTemplate生成绑定错误。

以下是我如何设置ContentControl的方法。内容绑定到选定选项卡的ViewModel,ContentTemplate绑定到DataTemplate,并带有该选项卡的视图。我以前使用ContentTemplateSelector而不是ContentTemplate的转换器,但是它有同样的问题,所以我尝试了这个。

<ContentControl Content="{Binding SelectedTab, Converter={StaticResource ConfigurationViewModelConverter}}" ContentTemplate="{Binding SelectedTab, Converter={StaticResource ConfigurationTemplateConverter}}"/>

也许我在某种程度上错误地解决了这个错误,但除了我在切换标签时遇到的绑定错误之外,一切都运行正常,似乎是由于Content和ContentTemplate短暂地不同步。提前感谢您的任何帮助。

1 个答案:

答案 0 :(得分:0)

所以,我在这个问题上迟到了将近2年,但是我在这个完全相同的问题上停留了大约一天,所以我想分享一下。我有3种类型的视图模型,分别对应3种不同的UserControls / DataTemplates。我用一种样式来解决这个问题

<ContentControl>
  <ContentControl.Resources>
    <DataTemplate x:Key="fooUc">
      <local:UC1 />
    </DataTemplate>
    <DataTemplate x:Key="barUc">
      <local:UC2 />
    </DataTemplate>
    <DataTemplate x:Key="bazUc">
      <local:UC3 />
    </DataTemplate>
  </ContentControl.Resources>
  <ContentControl.Style>
    <Style TargetType="ContentControl">
      <Style.Triggers>
        <!-- I'm assuming that SelectedTab is an int -->
        <DataTrigger Binding="{Binding SelectedTab}" Value="0">
          <Setter Property="Content" Value="{Binding FooVm}" />
          <Setter Property="ContentTemplate" Value="{DynamicResource fooUc}" />
        </DataTrigger>
        <DataTrigger Binding="{Binding SelectedTab}" Value="1">
          <Setter Property="ContentTemplate" Value="{DynamicResource barUc}" />
          <Setter Property="Content" Value="{Binding BarVm}" />
        </DataTrigger>
        <DataTrigger Binding="{Binding SelectedTab}" Value="2">
          <Setter Property="ContentTemplate" Value="{DynamicResource bazUc}" />
          <Setter Property="Content" Value="{Binding BazVm}" />
        </DataTrigger>
      </Style.Triggers>
    </Style>
  </ContentControl.Style>
</ContentControl>

上面要注意的关键是我的二传手的排序。如果必须在视图模型对象之前更改视图对象,则将其放在前面,否则将颠倒顺序。问题在于,一个必须先更改,另一个不能完全同时更改。如果您的控件彼此完全不同,则仍然会产生错误(尽管有所不同!)。这对我有用,因为BarVm和BazVm具有FooVm属性的子集。