繁体   English   中英

更改 ContentControl 绑定会导致空 DataContext

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

也许你们中的一位可以就以下问题启发我。 我使用列表框作为在 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;

         }
      }
   }
}

我创建了 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 实际上具有与 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");
         }

      }

   }
}

SecondView 不包含任何控件。

当 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");
     }

  }

我宁愿不必处理寻找空 DataContext 的选择更改。 相反,我想知道实际发生了什么。 谢谢。

发生这种情况的原因是,当ContentControlContent属性通过数据绑定设置为FirstViewModel时, FirstViewDataContext由 WPF 隐式连接。

一旦绑定更改为SecondViewModelFirstViewModel就会超出范围,因此 WPF 会自行清理,删除FirstViewModelFirstView及其隐式DataContext绑定。

我希望这有帮助。

暂无
暂无

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

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