0

在我之前的问题中,我相信我并不清楚,所以我没有得到任何可以帮助的答案,所以也许我会发布一些代码示例。绿屏.xaml

<UserControl x:Class="WPFTut.GreenScreenView"
         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" 
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300">
<Grid Background="Green">
    <Label Content="{Binding ScreenViewModel.ScreenName}"/>
    <Label Content="{Binding ScreenViewModel.UniqueProperty}"/>
</Grid>

RedScreen.xaml

<UserControl x:Class="WPFTut.RedScreenView"
         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" 
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300">
<Grid Background="Red">
    <Label Content="{Binding ScreenViewModel.ScreenName}"/>
</Grid>

主文件

<Window x:Class="WPFTut.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
<Grid x:Name="LayoutRoot">
</Grid>

IScreenViewModel.cs

namespace WPFTut
{
    interface IScreenViewModel
    {
        string ScreenName { get; set; }
    }
}

RedScreenViewModel.cs

namespace WPFTut
{
    class RedScreenViewModel:IScreenViewModel
    {
        public string ScreenName
        {
            get; set;
        }
    }
}

GreenScreenViewModel.cs

  namespace WPFTut
    {
    class GreenScreenViewModel : IScreenViewModel
    {
        public string ScreenName { get; set; }

        public string UniqueProperty { get; set; }
    }
   }

ScreenViewModelWrapper.cs

using System.ComponentModel;

namespace WPFTut
{
    class ScreenViewModelWrappers : INotifyPropertyChanged
    {
        private IScreenViewModel screenViewModel;

        private IScreenViewModel ScreenViewModel
        {
            get { return screenViewModel; }
            set
            {
                if (screenViewModel != value)
                {
                    screenViewModel = value;
                    OnPropertyChanged("ScreenViewModel");
                }
            }
        }

        public void SwapViewModel(MainWindow mainWindow)
        {
            //Yeah it was done statically, but in my original code, it is actually dynamic to switch between 
            //any screens. Just to keep it simlpe
            mainWindow.LayoutRoot.Children.Clear();
            mainWindow.LayoutRoot.Children.Add(new GreenScreenView()); // here add randomly chosen screen from array of screens.
            mainWindow.UpdateLayout(); //it doesn't refresh the visual tree. So if a red screen was selected next, an exception is thrown
            ScreenViewModel = new GreenScreenViewModel(); //
        }
        protected void OnPropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            var s = new PropertyChangedEventArgs(propertyName);
            if (handler != null)
            {

                handler(this, s);
            }
        }
        public event PropertyChangedEventHandler PropertyChanged;
    }
}

这就是我可以写的快速示例。同样,在 ViewModelWrapper 中,屏幕是根据用户输入动态选择的。现在假设首先选择了 GreenScreenView,当您删除并清除添加 RedScreen 并在尝试更新绑定时将 ScreenViewModel 更改为 RedScreenViewModel 时,它仍然会看到 GreenScreenView!因此它试图寻找这个:

<Label Content="{Binding ScreenViewModel.UniqueProperty}"/>

但是该代码不属于 RedScreenView,那么如何更新可视化树以查看正确的 xaml 树?因为它抛出了 NullReferenceException。我真的不知道我是否可以更清楚。再次感谢。

链接到上一个问题: Refresh View databindings using UpdateLayout or some other alternative

4

0 回答 0