我使用MVVM模式,但现在我的WorkspaceViewModel中的ObservableCollection出现问题。
我想从“ NavigationView”中创建“ WorkspaceView”中的TabItem。这不是Commands和EventAggregator的问题。 然后,我遇到了一个问题,即TabItem丢失了所有信息,因为在TabItem_Changed之后重新创建了ViewModel。这已通过扩展TabControl修复。 Here
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标头不会更改。标题是每次“客户”且EditMode = true时。 之后,我查看WorkspaceViewModel中的ObservableCollection。没有任何更改。它具有“标题=客户”和“ EditMode = true”
那么为什么CustomerViewModel中的更改未应用WorkspaceViewModel.ObservableCollection?
有人可以帮我吗?
编辑:
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都继承自Prism 7的 ViewModelBase 和 BindableBase 具有INotifyPropertyChanged
编辑2:解决方案
我发现了错误。如果我创建一个新的TabItem,我也会创建一个新的ViewModel。但是在XAML中,我也创建了一个新的ViewModel。因此,视图在WorkspaceViewModel中没有与ObservableCollection相同的ViewModel。 因此,我删除了XAML中的DataContext,现在它可以工作了。
<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>