Is it okay to pass my model into my view model via its constructor through MVVM practices?

public class LDLTrackViewModel : RailwayViewModel {      private LDLTrack _ldlTrack;        public LDLTrack LDLTrack {         get => _ldlTrack;         set { _ldlTrack = value;             OnPropertyChanged("LDLTrack");         }     }      public LDLTrackViewModel(LDLTrack ldlTrack) {         LDLTrack = ldlTrack;           LineCoords = new ObservableCollection<LineCoordinates>(ldlTrack.LineCoordList);          ZIndex = -50;      } 

}

My system is set up that I’ve filled my models with data through reading a big file. I then pass these models to various view models via their constructor (I have the same amount of view models as I do models):

LDLTracks = new ObservableCollection<LDLTrackViewModel>(TrainSimAllData.AllLDLTracks.Select(ldl => new LDLTrackViewModel(ldl))); 

Where LDLTracks is a collection of LDLTrackViewModels. I then bind to this list of view models in my view. I’m wondering if this is the normal way to go about things or whether there’s a better approach?

Swift MVVM: Repositories – loading entities and dependency injection

I create a lexikon and a navigation for ZOO. I use MVVM architecture supported by ReactiveSwift. I have a few questions about my practises and whether I could write my repositories better and more clearly.

I would like to know whether is it good to create a generic Repository class and inherited class from this class for loading one kind of entities. Is it suitable to create a parent Repository class and create child classes implementing a suitable protocol used for dependency injection for each kind of entity in this case?

I also work with three types of bindings with animal: FoodBinding – binding between an animal and a kind of food which the animal eats, BiotopeBinding – binding between an animal and a biotope in which the animal lives, ContinentBinding – binding between an animal and a continent in which the animal lives.

I would like to ask you whether is it good to create one class for each type of binding or create a parent class for all kinds of bindings. Is it good to create one repository class for all types of bindings or create a class for each kind of binding? If I would create a class for each kind of binding, is it good to have a parent class for all kinds of binding with a generic functions for all kinds of bindings?

Here is the content of the file AppDependency.swift in Service/Dependency directory. The class AppDependency is used for injection of dependencies in whole application (ViewModels, FlowCoordinators etc.). I think that it is a good practice to use protocols for each service which we want to inject. Is it really a good practice in my case, or not?

import UIKit   /**  This class is used for injection of some dependencies (especially repositories and services) to other code (especially ViewModels and ViewControllers)  */ class AppDependency {     private init() {}     /// instance of AppDependency class used for dependency injection     static let shared = AppDependency()      lazy var animalRepository:AnimalRepositoring =  AnimalRepository()     lazy var localityRepository:LocalityRepositoring =  LocalityRepository()     lazy var speechService: SpeechServicing = SpeechService(language: Locale.current.identifier)     lazy var biotopeBindingRepository: BiotopeBindingRepositoring = BiotopeBindingRepository()     lazy var foodBindingRepository: FoodBindingRepositoring = FoodBindingRepository()     lazy var continentBindingRepository: ContinentBindingRepositoring = ContinentBindingRepository() }  extension AppDependency: HasAnimalRepository{} extension AppDependency: HasLocalityRepository{} extension AppDependency: HasSpeechService{} extension AppDependency: HasContinentBindingsRepository{} extension AppDependency: HasBiotopeBindingsRepository{} extension AppDependency: HasFoodBindingsRepository{} 

Here is the content of the file Repository.swift in Service/Repository directory

import UIKit import ReactiveSwift   class Repository<T: LoadedEntity>{     /// array of entities which is used for storing information loaded from the NodeJS server     lazy var entities = MutableProperty<[T]?>([])     /// date of last editation or loading of array of entities     private var lastEdited: Date = Date()       /**      This function ensures loading data from server and      */     func loadAndSaveDataIfNeeded(){         // if data were loaded unsuccessfully after the starting of the application         if (entities.value == nil){             // updating of result in case that data could not be loaded previously             let result: [T]? = APIService.getEntitiesGotByAPICall(relativeUrl: T.relativeUrl)             if (result != nil){                 entities.value = result                 self.lastEdited = Date()             }          // after the starting of the application         } else if (entities.value!.count == 0){             // loading of the data in the beginning             let result: [T]? = APIService.getEntitiesGotByAPICall(relativeUrl: T.relativeUrl)             entities.value = result             self.lastEdited = Date()          // in other cases - data were loaded successfully last time         } else {             // updating of loaded data each 3 hours             let threeHoursAgo:Date = Date(timeIntervalSinceNow: -3*60*60)              // updating of loaded data when data was loaded more than 3 hours ago             if (self.lastEdited < threeHoursAgo){                 let result: [T]? = APIService.getEntitiesGotByAPICall(relativeUrl: T.relativeUrl)                 if (result != nil){                     entities.value = result                     self.lastEdited = Date()                 }             }         }     }  } 

Here is the content of the file BindingRepository.swift in Service/Repository directory

// //  BindingRepository.swift //  courseworkZoo // //  Created by Daniel Šup on 22/06/2019. //  Copyright © 2019 Daniel Šup. All rights reserved. // import UIKit import ReactiveSwift  /**  This protocol is created for the dependency injection. This protocol ensures loading the repository for working with bindings between biotopes and animals.  */ protocol BiotopeBindingRepositoring{     var entities: MutableProperty<[BiotopeBinding]?> { get }     func loadAndSaveDataIfNeeded()     func findBindingsWithAnimal(animal: Int) -> [BiotopeBinding]? }  /**  This protocol is created for the dependency injection. This protocol ensures loading the repository for working with bindings between kinds of food and animals.  */ protocol FoodBindingRepositoring{     var entities: MutableProperty<[FoodBinding]?> { get }     func loadAndSaveDataIfNeeded()     func findBindingsWithAnimal(animal: Int) -> [FoodBinding]?  }  /**  This protocol is created for the dependency injection. This protocol ensures loading the repository for working with bindings between continents and animals.  */ protocol ContinentBindingRepositoring{     var entities: MutableProperty<[ContinentBinding]?> { get }     func loadAndSaveDataIfNeeded()     func findBindingsWithAnimal(animal: Int) -> [ContinentBinding]?  }    /**  This class is a child of Repository class in which it is stored array of entities with the name entities of type MutableProperty. This class ensures finding bindings to the animal given by an identificator.  */ class BindingRepository<B: Bindable> : Repository<B>{      /**      This function finds bindings between the animal given by the identificator.      - Parameters:         - animal: The identificator of the animal which we find bindings for.      - Returns: Array of bindings with the given identificator of the animal or nil if array of bindings is not correctly loaded.      */     func findBindingsWithAnimal(animal: Int) -> [B]?{         if let bindings = self.entities.value as? [B]{             var bindingEntities: [B] = []             for binding in bindings{                 if(binding.getAnimalId() == animal){                     bindingEntities.append(binding)                 }             }             return bindingEntities         } else {             return nil         }     }  }    // These classes created for simpler dependency injection. These classes are childs of parent class BindingRepository for finding bindings between biotopes, kinds of food and continents and animals. class BiotopeBindingRepository: BindingRepository<BiotopeBinding>, BiotopeBindingRepositoring{ }  class FoodBindingRepository: BindingRepository<FoodBinding>, FoodBindingRepositoring{ }  class ContinentBindingRepository: BindingRepository<ContinentBinding>, ContinentBindingRepositoring{ } 

Here is the content of the file AnimalRepository.swift in Service/Repository directory

import UIKit import ReactiveSwift   protocol AnimalRepositoring{     var entities: MutableProperty<[Animal]?> { get }     func loadAndSaveDataIfNeeded()     func findAnimalById(id: Int) -> SignalProducer<Animal?, LoadError>     func findAnimalInCloseness(latitude: Double, longitude: Double) -> SignalProducer<Animal?, LoadError> }   class AnimalRepository: Repository<Animal>, AnimalRepositoring{      func findAnimalById(id: Int) -> SignalProducer<Animal?, LoadError> {         if let animalList = self.entities.value as? [Animal] {             for animal in animalList{                 if(animal.id == id){                     return SignalProducer(value: animal)                 }             }             return SignalProducer(value: nil)         } else {             return SignalProducer(error: .noAnimals)         }     }      func findAnimalInCloseness(latitude: Double, longitude: Double) -> SignalProducer<Animal?, LoadError> {         if let animalList = self.entities.value as? [Animal] {             for animal in animalList{                 if(abs(animal.latitude - latitude) < BaseViewModel.closeDistance && abs(animal.longitude - longitude) < BaseViewModel.closeDistance){                     return SignalProducer(value: animal)                 }             }             return SignalProducer(value: nil)         } else {             return SignalProducer(error: .noAnimals)         }     }   } 

Here is the content of the file LocalityRepository.swift in Service/Repository directory

import UIKit import ReactiveSwift   protocol LocalityRepositoring{     var entities: MutableProperty<[Locality]?> { get }     func loadAndSaveDataIfNeeded()     func findLocalityInCloseness(latitude: Double, longitude: Double) -> SignalProducer<Locality?, LoadError> }   class LocalityRepository: Repository<Locality>, LocalityRepositoring{       func findLocalityInCloseness(latitude: Double, longitude: Double) -> SignalProducer<Locality?, LoadError> {         if let localities = self.entities.value as? [Locality]{             for locality in localities{                 if(abs(locality.latitude - latitude) < BaseViewModel.closeDistance && abs(locality.longitude - longitude) < BaseViewModel.closeDistance){                     return SignalProducer(value: locality)                 }             }             return SignalProducer(value: nil)          } else {             return SignalProducer(error: .noLocalities)         }     }   } 

In my codes you can see that I created protocols for loading each kind of entities and classes implemented these protocols. I would like you to ask it is a problem (for code quality) that method loadAndSaveDataIfNeeded and entities property is implemented only in the parent Repository or method findBindingsWithAnimal only in the BindingRepository (in case of BindingRepositories) class or not. If it would be solved by better and more clear way, I would like to know how to refactor my code.

Is attempt like this, when using Application class, breaking MVVM pattern?

In my application I am using two view models. MainViewModel if fiered when MianWindow is initialized. And UpdateViewModel is fiered when UpdateWindow is initialized.

The update VM is supposed to use data from collection that is a property of the main VM and has its instance laready, and I need to refer to it somehow. And I was wondering, is refering to this collection with MainViewModel vm = (MainViewModel)win.DataContext; is breaking MVVM pattern or testability somehow or is any kind of antipattern? Thank you.

The code:

public class UpdateViewModel : ViewModelBase     {         public UpdateViewModel()         {             Jockeys = new ObservableCollection<LoadedJockey>();              PopulateCollections();         }          private void PopulateCollections()         {             MainWindow win = Application.Current.Windows.OfType<MainWindow>().FirstOrDefault();             MainViewModel vm = (MainViewModel)win.DataContext;              Jockeys = vm.Jockeys; //is it ok?              vm.Jockeys //is it ok?         }          public ObservableCollection<LoadedJockey> Jockeys { get; private set; }      } 

WPF MVVM validate property before setting when user’s change value in DataGrid [migrated]

Issue: I have a list of a class that’s being displayed in a Datagrid, one of the values needs to ask the user if they really want to change it. This was implemented with a YesNo MessageBox in the value’s Setter.

The problem is that this messagebox should not come up every time the Setter is called, like when a new object is being added to the datagrid with a dialog, it will still ask if you are sure you want to change the value of what is currently being created.

I’m not sure if there’s a clean way of doing this, so any help is appreciated.

Right now the setter in the class looks like this:

public string Value {   get { return _value; }   set    {        string message = "Are you sure you want to modify this value?";        MessageBoxResult result = MessageBox.Show(message, "Confirmation",        MessageBoxButton.YesNo, MessageBoxImage.Question);        if (result == MessageBoxResult.Yes)        {           _value = value;        }        else        {         // Set to previously used value         Value = _value;        }           RaisePropertyChanged("Value");   } } 

Закрытие окна через usercontrol (mvvm)

Собственно вопрос. Были мысли сделать подобное через relative source, но как это передать в код – не знаю. Желательно с минимальным количеством кода, выходящего за пределы UserControl’a

WPF MVVM Prism ComboBox не правильно работает привязка SelectedItem

Итак есть Datagrid у него в качестве колонки указано:

<DataGridTemplateColumn   Header="Валюта">     <DataGridTemplateColumn.CellTemplate>         <DataTemplate>             <TextBlock Text="{Binding Path=ExchangeRates.Title}"/>         </DataTemplate>     </DataGridTemplateColumn.CellTemplate>     <DataGridTemplateColumn.CellEditingTemplate>         <DataTemplate>             <ComboBox ItemsSource="{Binding Path=DataContext.ExchangeRates,               RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}"               SelectedItem="{Binding Path=ExchangeRates, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"                DisplayMemberPath="Title" IsSynchronizedWithCurrentItem="True"/>         </DataTemplate>     </DataGridTemplateColumn.CellEditingTemplate> </DataGridTemplateColumn> 

Datagrid привязан к списку товара. В коллекцию товар добавляется вот так:

/*ExchangeRates коллекция для ComboBox      Тут была попытка получить элемент из коллекции и потом его поставить в качестве выбранного(не помогло) ModelModul.ExchangeRates ex = ExchangeRates.Single(objEx =>  objEx.Id == product.ExchangeRates.Id); ExchangeRates.Contains(ex) хотя тут вернул true*/ PurchaseInfos.Add(new PurchaseInfos {     Products = new Products     {         Barcode = product.Barcode,         Groups = product.Groups,         //ExchangeRates = ex,         ExchangeRates = product.ExchangeRates,         Id = product.Id,         IdExchangeRate = product.IdExchangeRate,         IdGroup = product.IdGroup,         IdUnitStorage = product.IdUnitStorage,         IdWarrantyPeriod = product.IdWarrantyPeriod,         PurchasePrice = product.PurchasePrice,         SalesPrice = product.SalesPrice,         VendorCode = product.VendorCode,         UnitStorages = product.UnitStorages,         WarrantyPeriods = product.WarrantyPeriods,         Title = product.Title,         SerialNumbers = new ObservableCollection<SerialNumbers>()     },     IdProduct = product.Id,     IdExchangeRate = product.IdExchangeRate,     ExchangeRates = product.ExchangeRates }); 

Еще есть в классе ExchangeRates:

public override bool Equals(Object obj) {     if (obj == null || !GetType().Equals(obj.GetType()))     {     return false;     }     return Id == ((ExchangeRates)obj).Id &&              Title == ((ExchangeRates)obj).Title && Course == ((ExchangeRates)obj).Course; } 

Итог в TextBlock все отображается корректно, в ComboBox при первом редактировании выбранный элемент не соответствует тому который хранился. В нем в принципе выбран странный элемент, потому как в коллекции из двух элементов, если был выбран первый он укажет что выбран второй, а если второй то – первый. Во всех последующих редактированиях элемента отображается все корректно. И при отображении в Equals передаются два элемента с одинаковыми параметрами, но среди них нет того кто который должен быть реально выбран.

Where do I save a Canvas “center position” coordinate in an MVVM architecture?

Assume I have a canvas that has rendered shapes. I can drag-move around that canvas as if I was in a zoomed in image to move all shapes around. Between the Model and ViewModel I have a ServiceLayer (or Controller, however you’d like to call that ) that generates shapes based on generic object-logic and applies the necessary styles, which it then feeds to the ViewModel. Although not completely traditional MVVM, it’s the solution I came up with thinking about how to change the CanvasBehaviour at runtime without switching ViewModels. Now if I want to switch the underlying generic service (perhaps because another tool was selected) I need to save what the current center position is.

It seems like a nitpicky question, but I feel like since I cannot answer this fully and with determination, I might have misunderstood something about the architecture. Here’s what I’m thinking:

  1. It should not be saved in the Model. The model is for all the underlying shapes etc. and has nothing to do with how they’re displayed.
  2. It should not be in the ServiceObject, since it can change dynamically at runtime based on tools and it “feels” wrong to read out the previous center and feed it to a new ServiceObject before replacing it.
  3. It might belong in the ViewModel. the ViewModel prepares the data it receives into the necessary binded collections. I can keep a reference of the center here, and modify the incoming shapes etc. to translate them around this center point. However that means that the “move” tool now needs a reference towards this ViewModel, to tell it how it changed or similarily, but the tools are supposed to be contained in the ServiceObject entirely.
  4. It does definitely not belong in the view, I think.

Binding between View and ViewModel using RxSwift in MVVM

I am building a simple login page which will check for username before navigating to another screen and here is how I am doing the binding now. I would like to know if I am doing it right and if I am not, what is the recommended way of doing the binding. Moreover, I creating the UI programmatically.

ViewModel.swift

// Inputs private let usernameSubject = PublishSubject<String>() private let nextButtonDidTapSubject = PublishSubject<Void>()  // Outputs private let validUsernameSubject = PublishSubject<Bool>() private let invalidUsernameSubject = PublishSubject<String>()  // MARK: - Init  init() {      input = Input(username: usernameSubject.asObserver(),                   nextButtonDidTap: nextButtonDidTapSubject.asObserver())      output = Output(validUsername: validUsernameSubject.asObservable(),                     invalidUsername: invalidUsernameSubject.asObservable())      nextButtonDidTapSubject         .withLatestFrom(usernameSubject.asObservable())         .subscribe(onNext: { [unowned self] text in             if text.count >= self.minUsernameLength {                 self.validUsernameSubject.onNext(true)             } else {                 let message = text.count > 0 ?                     "Please enter a valid username" :                     "Please enter a username"                 self.invalidUsernameSubject.onNext(message)             }         })         .disposed(by: disposeBag)  } 

ViewController.swift

private func configureBinding() {      loginLandingView.usernameTextField.rx.text.orEmpty         .subscribe(viewModel.input.username)         .disposed(by: disposeBag)      loginLandingView.nextButton.rx.tap         .subscribe(viewModel.input.nextButtonDidTap)         .disposed(by: disposeBag)      viewModel.output.validUsername         .subscribe(onNext: { [unowned self] _ in             print("Valid username - Navigate...")             self.navigate()         })         .disposed(by: disposeBag)      viewModel.output.invalidUsername         .subscribe(onNext: { [unowned self] message in             self.showAlert(with: message)         })         .disposed(by: disposeBag)  }