ObservableCollection с ModelView не изменился - PullRequest
0 голосов
/ 15 ноября 2018

Я использую шаблон 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>

...