私は次のようなコンテンツコントロールを持っています:
<ContentControl x:Name="grid1ContentControl" Content="{Binding MainGridViewModel}" />
MainGridViewModelは、タイプMainGridViewModelTypeのプロパティです。
次のようなDataTemplateもあります。
<DataTemplate DataType="{x:Type App:MainGridViewModelType}">...
MainGridViewModelプロパティを初期化(つまり設定)し、NotifyPropertyChangedイベントを発生させます。
この時点で、MainGridViewModelを設定し、ContentControlでのバインドの結果として、MainGridViewModelプロパティタイプ(つまり、MainGridViewModelType)に一致するDataTemplateコンテンツをその場所のビジュアルツリーに追加することをフレームワークに通知する必要があります。 ContentControlが配置されている場所。
実際、RaisePropertyChanged()メソッドがMainGridViewModelプロパティのセッターで実行されているのを見ることができます。ただし、ビジュアルツリーインスペクターを使用してビジュアルツリーを検査する場合、MainGridViewModelの初期化後、ContentControlのContentPresenterはDataTemplateのコンテンツを表示しません。なんで?
ユーザーの操作に応じてMainGridViewModelを再度設定した後、期待したビジュアルツリーの更新を取得することに注意してください。
私が思いついた唯一の回避策は、DataTemplate ax:Keyを指定し、ContentControlのContent値を明示的に設定し、タイプをそのDataTemplateに一致させるフレームワークに依存せず、それを適用することです。
ContentControl grid1ContentControl = VisualElementFinder.FindDescendantByName(mwin, "grid1ContentControl") as ContentControl;
grid1ContentControl.SetValue(ContentControl.ContentTemplateProperty, mwin.FindResource("MainGridViewModelKey") as DataTemplate);
私は同じ問題にぶつかり続けます。ビジュアルが初期化された後、フレームワークがバインドされたプロパティの後続の割り当てにどのように反応することが期待されるかについての私の理解にはギャップがあります。以下に説明するように、私はウィルの提案を取り入れてプロトタイプを開発しました。今後ともよろしくお願いいたします。
これは、このテーマに関する私のブログエントリへのリンクです。プロトタイププロジェクトへの直接リンクは次のとおりです。
これは、さらに議論するためのコンテキストを提供するMainWindowコードです。プロトタイププロジェクトでは、NewTabControlViaContentControlCommandは機能しますが、NewTabControlCommandは機能しません。
MainWindow.xaml:
<Window x:Class="DynamicTabControlSimpleProto.View.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vm="clr-namespace:DynamicTabControlSimpleProto.ViewModel"
xmlns:vw="clr-namespace:DynamicTabControlSimpleProto.View"
xmlns:diag="clr-namespace:System.Diagnostics;assembly=WindowsBase"
mc:Ignorable="d"
Height="300"
Width="500"
Title="Dynamic TabControl Prototype"
DataContext="{Binding Main, Source={StaticResource Locator}}">
<Window.Resources>
<DataTemplate DataType="{x:Type vm:TabControlViewModel}">
<vw:TabControlUserControl />
</DataTemplate>
<DataTemplate x:Key="tabControlDataTemplate">
<vw:TabControlUserControl />
</DataTemplate>
</Window.Resources>
<Grid x:Name="LayoutRoot">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="4" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<StackPanel Name="stackPanel" Grid.Column="0">
<Button
Content="NewTabControl"
Command="{Binding NewTabControlCommand}"
CommandParameter="{Binding Path=DataContext}" />
<Button
Content="NewTabControlViaContentControl"
Command="{Binding NewTabControlViaContentControlCommand}"
CommandParameter="{Binding ElementName=tabControlContentControl}" />
</StackPanel>
<DockPanel
Name="dockPanel"
Grid.Column="2">
<Border
BorderBrush="Blue"
BorderThickness="5">
<ContentControl x:Name="tabControlContentControl" DataContext="{Binding TabControlViewModel, diag:PresentationTraceSources.TraceLevel=High}" />
</Border>
</DockPanel>
</Grid>
</Window>
MainWindowViewModel.cs
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using System.Windows.Controls;
using DynamicTabControlSimpleProto.View;
using System.Windows;
namespace DynamicTabControlSimpleProto.ViewModel
{
public class MainViewModel : ViewModelBase
{
public string Welcome
{
get
{
return "Welcome to MVVM Light";
}
}
/// <summary>
/// Initializes a new instance of the MainViewModel class.
/// </summary>
public MainViewModel()
{
NewTabControlCommand = new RelayCommand<object>(obj =>
{
this.NewTabControl(obj);
});
NewTabControlViaContentControlCommand =
new RelayCommand<ContentControl>(tabControlContentControl =>
{
this.NewTabControlViaContentControl(tabControlContentControl);
});
}
public TabControlViewModel TabControlViewModel
{
get
{
return _tabControlViewModel;
}
private set
{
_tabControlViewModel = value;
RaisePropertyChanged("TabControlViewModel");
}
}
public RelayCommand<object> NewTabControlCommand
{
get;
private set;
}
private TabControlViewModel _tabControlViewModel = null;
void NewTabControl(object obj)
{
TabControlViewModel = new TabControlViewModel();
}
public RelayCommand<ContentControl> NewTabControlViaContentControlCommand
{
get;
set;
}
void NewTabControlViaContentControl(ContentControl tabContentControl)
{
TabControlViewModel = new TabControlViewModel();
MainWindow mwin = Application.Current.MainWindow as MainWindow;
tabContentControl.SetValue(ContentControl.ContentTemplateProperty, mwin.FindResource("tabControlDataTemplate") as DataTemplate);
}
}
}