Я использую шаблон MVVM, но теперь у меня есть проблема с ObservableCollection в моей WorkspaceViewModel.
Я хочу создать из «NavigationView» TabItem в моем «WorkspaceView». Это не проблема с командами и EventAggregator.
Тогда у меня возникла проблема, TabItem потерял всю информацию, потому что после TabItem_Changed ViewModel был воссоздан. Это было исправлено с помощью расширенного TabControl. Здесь
ViewModel: WorkspaceViewModel
public class WorkspaceViewModel : ViewModelBase.ViewModelBase
{
public WorkspaceViewModel()
{
this.TabItems = new ObservableCollection<ViewModelBase.ViewModelBase>();
CreateTabItemEvent.Instance.Subscribe(CreateTabItem);
}
#region Properties
private ViewModelBase.ViewModelBase _SelectedTabItem;
public ViewModelBase.ViewModelBase SelectedTabItem
{
get { return _SelectedTabItem; }
set { SetProperty(ref _SelectedTabItem, value); }
}
private ObservableCollection<ViewModelBase.ViewModelBase> _TabItems;
public ObservableCollection<ViewModelBase.ViewModelBase> TabItems
{
get { return _TabItems; }
set { SetProperty(ref _TabItems, value); }
}
#endregion
#region Methodes
private void CreateTabItem(string pObjectName)
{
//create TabItem and add it to the list
ViewModelBase.ViewModelBase newTabItem = null;
//Test Objects from Buttonnames
if (pObjectName.EndsWith("1"))
{
newTabItem = new CustomerViewModel();
}
else if (pObjectName.EndsWith("2"))
{
newTabItem = new ContactViewModel();
}
if (newTabItem != null)
{
this.TabItems.Add(newTabItem);
this.SelectedTabItem = newTabItem;
//Test Refresh - not work because list is "old"
RaisePropertyChanged(nameof(this.TabItems));
}
}
#endregion
}
Просмотр: WorkspaceView
<UserControl.Resources>
<DataTemplate DataType="{x:Type viewmodel:CustomerViewModel}">
<view:CustomerView/>
</DataTemplate>
<DataTemplate DataType="{x:Type viewmodel:ContactViewModel}">
<view:ContactView/>
</DataTemplate>
<Style TargetType="{x:Type tabControlEx:TabControlEx}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabControl}">
<Grid Background="{TemplateBinding Background}" ClipToBounds="True" KeyboardNavigation.TabNavigation="Local" SnapsToDevicePixels="True">
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="ColumnDefinition0" />
<ColumnDefinition x:Name="ColumnDefinition1" Width="0" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition x:Name="RowDefinition0" Height="Auto" />
<RowDefinition x:Name="RowDefinition1" Height="*" />
</Grid.RowDefinitions>
<DockPanel Margin="2,2,0,0" LastChildFill="False">
<TabPanel x:Name="HeaderPanel" Margin="0,0,0,-1" VerticalAlignment="Bottom" Panel.ZIndex="1" DockPanel.Dock="Left"
IsItemsHost="True" KeyboardNavigation.TabIndex="1" />
</DockPanel>
<Border x:Name="ContentPanel" Grid.Row="1" Grid.Column="0"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
KeyboardNavigation.DirectionalNavigation="Contained" KeyboardNavigation.TabIndex="2" KeyboardNavigation.TabNavigation="Local">
<Grid x:Name="PART_ItemsHolder" Margin="{TemplateBinding Padding}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Text="Workspace Control"></TextBlock>
<tabControlEx:TabControlEx x:Name="tbWorkspace" Grid.Row="1"
ItemsSource="{Binding TabItems}" SelectedItem="{Binding SelectedTabItem}"
IsSynchronizedWithCurrentItem="True" >
<TabControl.ItemContainerStyle>
<Style TargetType="TabItem">
<Setter Property="Header" Value="{Binding Title}"/>
</Style>
</TabControl.ItemContainerStyle>
</tabControlEx:TabControlEx>
</Grid>
ViewModel: CustomerViewModel
public class CustomerViewModel : ViewModelBase.ViewModelBase
{
public CustomerViewModel()
{
this.SendMessageCommand = new DelegateCommand<string>(SendMessage);
this.Title = "Customer";
}
#region Commands
private ICommand _SendMessageCommand;
public ICommand SendMessageCommand
{
get { return _SendMessageCommand; }
set { SetProperty(ref _SendMessageCommand, value); }
}
#endregion
#region Methodes
private void SendMessage(string pMessage)
{
//Test to change the Title on the TabItem
this.Title = pMessage;
this.EditModus = false;
MessageSentEvent.Instance.Publish(pMessage);
}
#endregion
}
Теперь, если я нажимаю на кнопку, которая использует команду «SendMessageCommand», заголовок изменяется, но заголовок TabItem не изменяется. Заголовок каждый раз "Customer" и EditMode = true.
После этого я смотрю на ObservableCollection в WorkspaceViewModel ... Там нет никаких изменений. Он имеет "Title = Customer" и "EditMode = true"
Так почему же изменения из CustomerViewModel не применяются к WorkspaceViewModel.ObservableCollection?
Может кто-нибудь мне помочь?
Пример проекта
EDIT:
ViewModel: ViewModelBase
public class ViewModelBase : BindableBase
{
public ViewModelBase()
{
this.Title = String.Empty;
this.EditModus = true;
}
#region Properties
private string _Title;
public string Title
{
get { return _Title; }
set { SetProperty(ref _Title, value); }
}
private bool _EditModus;
public bool EditModus
{
get { return _EditModus; }
set { SetProperty(ref _EditModus, value); }
}
#endregion
}
все ViewModels наследуются от ViewModelBase и BindableBase от Prism 7 имеет INotifyPropertyChanged
РЕДАКТИРОВАТЬ 2: РЕШЕНИЕ
Я нашел ошибку. Если я создаю новый TabItem, я создаю новую ViewModel тоже. Но в XAML я создаю новую ViewModel тоже. Таким образом, View не имеет ту же ViewModel, что и ObservableCollection в WorkspaceViewModel.
Поэтому я удаляю DataContext в XAML, и теперь он работает.
<UserControl x:Class="CustomerModul.View.CustomerView"
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:CustomerModul.View"
xmlns:vm="clr-namespace:CustomerModul.ViewModel"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<UserControl.DataContext>
<vm:CustomerViewModel/>
</UserControl.DataContext>
<Grid>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<CheckBox Grid.Row="0" IsChecked="{Binding EditModus}">EditModus aktiv</CheckBox>
<Button Grid.Row="1" Command="{Binding SendMessageCommand}" CommandParameter="Gespeichert" Content="Save"></Button>
</Grid>