「TabViewModelItem」のコレクションにバインドされたTabControlを保持するMVVMパターンを使用して、WPFアプリケーションを作成しました。
メイン ウィンドウの XAML:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ViewModel="clr-namespace:XcomSavesGameEditor.ViewModel"
x:Class="XcomSavesGameEditor.MainWindow"
xmlns:Views="clr-namespace:XcomSavesGameEditor.View"
Title="X-COM Saved Game Editor" Height="650" Width="850" Background="#FF1B0000">
<Window.DataContext>
<ViewModel:TabsManagerViewModel/>
</Window.DataContext>
<Grid>
... (some not relevant code removed for clearity of question) ...
<TabControl x:Name="myTabs" Background="Black" Margin="0,25,0,0" BorderThickness="0,0,0,0" BorderBrush="Black" ItemsSource="{Binding Tabs}" >
<TabControl.Resources>
<DataTemplate DataType="{x:Type ViewModel:Tab0a_FileSaveData_ViewModel}">
<Views:Tab0a_FileSaveData_View />
</DataTemplate>
<DataTemplate DataType="{x:Type ViewModel:Tab0b_Summary_ViewModel}">
<Views:Tab0b_Summary_View />
</DataTemplate>
<DataTemplate DataType="{x:Type ViewModel:Tab1_Research_ViewModel}">
<Views:Tab1_Research_View />
</DataTemplate>
<DataTemplate DataType="{x:Type ViewModel:Tab2_Engineering_ViewModel}">
<Views:Tab2_Engineering_View />
</DataTemplate>
<DataTemplate DataType="{x:Type ViewModel:Tab3_Barracks_ViewModel}">
<Views:Tab3_Barracks_View />
</DataTemplate>
<DataTemplate DataType="{x:Type ViewModel:Tab4_Hangar_ViewModel}">
<Views:Tab4_Hangar_View />
</DataTemplate>
<DataTemplate DataType="{x:Type ViewModel:Tab5_SituationRoom_ViewModel}">
<Views:Tab5_SituationRoom_View />
</DataTemplate>
</TabControl.Resources>
<TabControl.ItemTemplate>
<!-- this is the header template-->
<DataTemplate>
<Grid Margin="0">
<Border Margin="0,0,0,0"
Background="Black"
BorderBrush="Black"
BorderThickness="0,0,0,0" Padding="0,0,0,0">
<StackPanel Orientation="Horizontal"
Margin="0,0,0,0">
<Image Name ="tabImage" Source="{Binding TabImage_Disabled}" />
</StackPanel>
</Border>
</Grid>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Path=IsSelected,RelativeSource={RelativeSource TemplatedParent}}" Value="True">
<Setter TargetName="tabImage" Property="Source" Value="{Binding TabImage_Enabled}"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</TabControl.ItemTemplate>
<TabControl.ContentTemplate>
<!-- this is the body of the TabItem template-->
<DataTemplate>
<Grid>
<Grid.Background>
<ImageBrush ImageSource="{Binding TabImage_Background}"/>
</Grid.Background>
<UniformGrid>
<ContentPresenter HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Content="{Binding TabContents}" />
</UniformGrid>
</Grid>
</DataTemplate>
</TabControl.ContentTemplate>
</TabControl>
タブのコレクションを保持する ViewModel はコードです。
public sealed class TabsManagerViewModel : ViewModelBase
{
private ObservableCollection<TabViewModelItem> _tabs;
public ObservableCollection<TabViewModelItem> Tabs
{
get { return _tabs; }
set
{
_tabs = value;
RaisePropertyChanged("Tabs");
}
}
public TabsManagerViewModel()
{
Tabs = new ObservableCollection<TabViewModelItem>();
Tabs.Add(new TabViewModelItem { TabName = "File_Save_Data", TabImage_Enabled = _aEnabledTabImages[(int)enum_Tabs.SaveFileData_Tab], TabImage_Disabled = _aDisabledTabImages[(int)enum_Tabs.SaveFileData_Tab], TabImage_Background = _aBackgroundTabImages[(int)enum_Tabs.SaveFileData_Tab], TabContents = new Tab0a_FileSaveData_ViewModel() });
Tabs.Add(new TabViewModelItem { TabName = "Summary", TabImage_Enabled = _aEnabledTabImages[(int)enum_Tabs.Summary_Tab], TabImage_Disabled = _aDisabledTabImages[(int)enum_Tabs.Summary_Tab], TabImage_Background = _aBackgroundTabImages[(int)enum_Tabs.Summary_Tab], TabContents = new Tab0b_Summary_ViewModel() });
... (rest of code removed for clearity of question)
}
}
基本的に、「TabViews」のコレクションにバインドされているのはタブ コントロールです。オブジェクトのデータ型に基づいて、View1 または View2 を表示しています。注: View1 と View 2 は UserControls であり、それぞれ独自の ViewModel にバインドされています。このコンセプトはうまく機能します。
今、あなたが私に尋ねる問題はどこにありますか? 私の問題は次のとおりです。別のタブをクリックしてから同じタブに戻るたびに、特定のタブ ViewModel コンストラクターが再度呼び出され、ViewModel オブジェクトが残ると予想されます。
タブを切り替えると、そのページで行った変更が失われるため、これは問題です。ctor は何度も何度も呼び出されるため、この情報を格納するために VIewModel を使用することさえできません。
私の質問は次のとおりです。1) タブが非アクティブのときに TabControl が ViewModel オブジェクトを破棄するのを防ぐ方法はありますか? すべてのViewModelのオブジェクトを事前に作成し、非表示のときにそれらを破棄しないことを意味しますか? 2)この概念を使用した「回避策」が存在するため、特定のタブの「ビジュアルツリー」を保存できるため、そこから移動して再度開くと、すべての情報が保存されます(選択したものなど)チェックボックス、書かれたテキストなど)
問題について何か助けていただければ幸いです。
よろしく、イダン