Контекст при добавлении новых элементов в Catel MVVM - PullRequest
0 голосов
/ 27 октября 2018

В Catel.MVVM: В случае, когда добавляет новый Customer, где свойство Id1 по-прежнему равно нулю, IdDocumentView будет иметь контекст IdDocumentViewModel при совпадениив конструкторе (который не имеет параметра IdDocument), ведущем к ViewModel без Model.Есть ли стандартный способ работы с этим сценарием, возможно, установив customer.Id1 для экземпляра IdDocument со значениями по умолчанию, чтобы у View был контекст, позволяющий привязке обновлять значения экземпляра IdDocument?

Структура:

MainView : Catel.Windows.Controls.UserControl

_ | - CustomerWindow : Catel.Windows.Window

___ | - IdDocumentView : Catel.Windows.Controls.UserControl

МодельКлассы:

public class Customer : Entity
{
    [DomainSignature]
    public string Code { get; set; }

    public Gender Gender { get; set; }

    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string MiddleName { get; set; }

    public DateTime DateOfBirth { get; set; }
    public Lookup PlaceOfBirth { get; set; }

    public string MobileNumber { get; set; }
    public string Email { get; set; }

    public ICollection<CustomerAddress> Addresses { get; set; }

    public Lookup Occupation { get; set; }

    public IdDocument Id1 { get; set; }

    public IdDocument Id2 { get; set; }

}

public class IdDocument : Entity
{
    [DomainSignature]
    public Lookup IdType { get; set; }

    [DomainSignature]
    public string IdCode { get; set; }

    [DomainSignature]
    public DateTime IdExpiry { get; set; }
}

В CustomerView

<DockPanel HorizontalAlignment="Stretch" Grid.ColumnSpan="2">
    <GroupBox Header="ID 1" DockPanel.Dock="Top" Margin="0">
        <local:IdDocumentView DataContext="{Binding Id1}" HorizontalAlignment="Stretch" />
    </GroupBox>
</DockPanel>
<orccontrols:EmptyColumn />
<DockPanel HorizontalAlignment="Stretch" Grid.ColumnSpan="2">
    <GroupBox Header="ID 2" DockPanel.Dock="Top" Margin="0">
        <local:IdDocumentView DataContext="{Binding Id2}" HorizontalAlignment="Stretch" />
    </GroupBox>
</DockPanel>

IdDocumentView

<catel:UserControl x:Class="CTT.MTS.Views.IdDocumentView"
                   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:CTT.MTS.Views"
                   xmlns:catel="http://schemas.catelproject.com"
                   xmlns:orccontrols="http://schemas.wildgums.com/orc/controls"
                   xmlns:app="clr-namespace:CTT.MTS.Model"
                   xmlns:controls="clr-namespace:CTT.MTS.Controls"
                   mc:Ignorable="d"
                   d:DesignHeight="800" d:DesignWidth="800">
    <orccontrols:StackGrid>

        <!-- Row definitions -->
        <orccontrols:StackGrid.RowDefinitions>
            <RowDefinition Height="40" />
            <RowDefinition Height="40" />
            <RowDefinition Height="40" />
        </orccontrols:StackGrid.RowDefinitions>

        <!-- Column definitions -->
        <orccontrols:StackGrid.ColumnDefinitions>
            <ColumnDefinition Width="100" />
            <ColumnDefinition Width="*" />
        </orccontrols:StackGrid.ColumnDefinitions>

        <Label Content="Type" />
        <ComboBox ShouldPreserveUserEnteredPrefix="False" IsEditable="False" ItemsSource="{Binding IdTypes}"
                  DisplayMemberPath="Value" SelectedValuePath="Value" SelectedValue="{Binding IdTypeText}" Width="100"
                  HorizontalAlignment="Left">
        </ComboBox>
        <Label Content="Code" />
        <TextBox Text="{Binding IdCode}" Width="100" HorizontalAlignment="Left"></TextBox>

        <Label Content="Expiry" />
        <orccontrols:DatePicker Width="120" HorizontalAlignment="Left" Margin="0" Height="40"
            Value="{Binding IdExpiry, ValidatesOnDataErrors=True, NotifyOnValidationError=True}">
        </orccontrols:DatePicker>
    </orccontrols:StackGrid>
</catel:UserControl>

в MainViewModel в командном методе для Button клика

 await uiVisualizerService.ShowAsync<CustomerViewModel>(new Customer
{
    DateOfBirth = new DateTime(1981, 8, 8),
    Gender = Gender.Male,
    FirstName = "Muhammad",
    Id1 = new IdDocument { IdType = idType, IdCode = "1111", IdExpiry = DateTime.Now.AddYears(-1) },
    //Id2 = new IdDocument(),
    Addresses = new List<CustomerAddress>(new[]
        {new CustomerAddress {Address = address, AddressType = addressType, IsCurrent = true}})
});

примечание * Инициализация Id2 прокомментирована.Если оставить так, null IdDocumentView не будет иметь ссылки на конструкторы IdDocument модель

IdDocumentViewModel

public IdDocumentViewModel(ILookupService lookupService)
{

    Argument.IsNotNull(() => lookupService);
    this.lookupService = lookupService;

    IdTypes = lookupService.IdTypes;

}

public IdDocumentViewModel(IdDocument idDocument, ILookupService lookupService) :this(lookupService)
{

    IdDocument = idDocument;
    IdTypeText = idDocument.IdType?.Value ?? "";
}

Обратите внимание, что я добавилпервый меньше аргументов конструктор после того, как заметил конструктор с параметром IdDocument, который не вызывается для Customer.Id1, когда он нулевой.

Есть идеи?

1 Ответ

0 голосов
/ 28 октября 2018

Вы полагаете, что:

  1. Catel сначала попытается создать виртуальную машину с впрыском модели
  2. Если это невозможно, он будет использовать тот, у которого будет максимально возможное количество параметров
  3. Если это невозможно, виртуальная машина не будет создана

В таких случаях я обычно передаю временную (новую) модель без идентификатора. Таким образом, «child vm» знает, что он находится в состоянии создания вместо редактирования.

...