简体   繁体   English

更改 ContentControl 绑定会导致空 DataContext

[英]Changing the ContentControl binding results in a null DataContext

Perhaps one of you could enlighten me on the following problem.也许你们中的一位可以就以下问题启发我。 I'm using a list box as a way to navigate between 2 viewmodels.我使用列表框作为在 2 个视图模型之间导航的方式。

<Window x:Class="MyWPFApp.ShellView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:cal="http://www.caliburnproject.org">

  <Grid Background="White">
     <Grid.ColumnDefinitions>
        <ColumnDefinition Width="2*"/>
        <ColumnDefinition Width="8*"/>
     </Grid.ColumnDefinitions>
     <ListBox Grid.Column="0" cal:Message.Attach="[Event SelectionChanged] 
= [Action onViewSelectionChange($this.SelectedItem.Text)]">
        <TextBlock Text="FirstView"/>
        <TextBlock Text="SecondView"/>
     </ListBox>
        <ContentControl Grid.Column="1" Content="{Binding MyViewModel}"/>
  </Grid>

namespace MyWPFApp
{
    public class ShellViewModel : Caliburn.Micro.PropertyChangedBase, IShell
   {
      private object _vm;

      public object MyViewModel
      {
         get { return _vm; }
         set { _vm = value; NotifyOfPropertyChange(() => MyViewModel); }
      }

      public FirstViewModel vm1;
      public SecondViewModel vm2;



      public ShellViewModel()
      {
         vm1 = new FirstViewModel();
         vm2 = new SecondViewModel();
         MyViewModel = vm1;

      }

      public void onViewSelectionChange(string str)
      {

         switch (str)
         {
            case "FirstView":
               MyViewModel = vm1;
               break;
            case "SecondView":
               MyViewModel = vm2;
               break;
            default:
               break;

         }
      }
   }
}

I've create 2 datatemplates to associate the viewmodel with its view我创建了 2 个数据模板来将视图模型与其视图相关联

<Application x:Class="MyWPFApp.App"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:local="clr-MyWPFApp">
  <Application.Resources>
  <ResourceDictionary>
     <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary>
           <local:AppBootstrapper x:Key="bootstrapper" />
        </ResourceDictionary>
     </ResourceDictionary.MergedDictionaries>
     <DataTemplate DataType="{x:Type local:FirstViewModel}">
        <Grid>
           <local:FirstView></local:FirstView>
        </Grid>
     </DataTemplate>
     <DataTemplate DataType="{x:Type local:SecondViewModel}">
        <Grid>
           <local:SecondView></local:SecondView>
        </Grid>
     </DataTemplate>
  </ResourceDictionary>
  </Application.Resources>
  </Application>

FirstView actually has controls which have bindings to properties in FirstViewModel FirstView 实际上具有与 FirstViewModel 中的属性绑定的控件

   <UserControl x:Class="MyWPFApp.FirstView"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
            xmlns:local="clr-namespace:MyWPFApp"
            xmlns:cal="http://www.caliburnproject.org"
            mc:Ignorable="d" 
            d:DesignHeight="300" d:DesignWidth="300">
  <Grid Background="Aquamarine">
     <ListBox SelectedIndex="{Binding SelectedIndex}" 
              SelectedItem="{Binding SelectedItem}"
              cal:Message.Attach="[Event SelectionChanged]=[Action OnLBSelectionChanged($source)]">
        <ListBoxItem>apple</ListBoxItem>
        <ListBoxItem>orange</ListBoxItem>
        <ListBoxItem>pear</ListBoxItem>
     </ListBox>
  </Grid>

using Caliburn.Micro;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MyWPFApp
{
   public class FirstViewModel : PropertyChangedBase
   {

      private int _selectedindex;

      public int SelectedIndex
      {
         get { return _selectedindex; }
         set { _selectedindex = value; NotifyOfPropertyChange(() => SelectedIndex); }
      }


      private string _selecteditem;

      public string SelectedItem
      {
         get { return _selecteditem; }
         set { _selecteditem = value; NotifyOfPropertyChange(() => SelectedItem); }
      }



      public FirstViewModel()
      {
      }


      public void OnLBSelectionChanged(System.Windows.Controls.ListBox lb)
      {
         if(lb.DataContext == null)
         {
            Debug.WriteLine("The DataContext is null");
         }

      }

   }
}

The SecondView contains no controls. SecondView 不包含任何控件。

When the ShellView list box selection changes from FirstView to SecondView, I've noticed that the FirstView ListBox DataContext becomes null.当 ShellView 列表框选择从 FirstView 更改为 SecondView 时,我注意到 FirstView ListBox DataContext 变为 null。

  public void OnLBSelectionChanged(System.Windows.Controls.ListBox lb)
  {
     if(lb.DataContext == null)
     {
        Debug.WriteLine("The DataContext is null");
     }

  }

I would prefer not to have to handle selection changes looking for a null DataContext.我宁愿不必处理寻找空 DataContext 的选择更改。 Instead, I'd like to know what's actually happening.相反,我想知道实际发生了什么。 Thanks.谢谢。

The reason why this is happening is that the DataContext for FirstView is implicitly wired up by WPF when the ContentControl 's Content property is set to the FirstViewModel via data binding.发生这种情况的原因是,当ContentControlContent属性通过数据绑定设置为FirstViewModel时, FirstViewDataContext由 WPF 隐式连接。

Once the binding changes to be SecondViewModel the FirstViewModel goes out of scope and thus WPF cleans up after itself, removing FirstViewModel , FirstView , and its implicit DataContext binding.一旦绑定更改为SecondViewModelFirstViewModel就会超出范围,因此 WPF 会自行清理,删除FirstViewModelFirstView及其隐式DataContext绑定。

I hope this helps.我希望这有帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM