以前の質問では、私が明確ではなかったと思うので、役立つ回答が得られなかったので、コード例をいくつか投稿します。GreenScreen.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>
Main.xaml
<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 をスローしているためです。もっとはっきりさせられるかどうかは本当にわかりません。再度、感謝します。