MVVM Light tworzenie RelayComand

0

Zastanawiam się czy dobrze robię dodając Commands do mojego widoku. Komendy dodaję w klasie ViewModelu o tak :

 public RelayCommand LoadCommand
        {
            get
            {
                return new RelayCommand(new Action(() =>
                {
                    var dlg = new OpenFileDialog();
                    bool? result = dlg.ShowDialog();
                    if (result == true)
                    {
                        FileIO.LoadZip(new Uri(dlg.FileName, UriKind.RelativeOrAbsolute), MyEnums.DirsKeyWords.Source);
                    }
                }));
            }
        }

a za pomocą Lokatora z MVVM Light binduję komendę w Widoku


DataContext="{Binding Main, Mode=OneWay, Source={StaticResource Locator}}"

<MenuItem Header="Load" Command="{Binding LoadCommand}" />
 

Czy to tak się robi czy tworzycie nowe klasy dla komend i nie trzymacie ich w ViewModelu ?

1

U mnie jest tak:

View

 
<Button Name="rap5_Button" Style="{StaticResource ResourceKey=PodstawowyFioletowyButton}" Command="{Binding Path=rap5_Command}">Różnica</Button>

ViewModel

 
 private RelayCommand<object> _rap5_Command; //Różnica
        public ICommand rap5_Command
        {
            get
            {
                if (_rap5_Command == null)
                {
                    _rap5_Command = new RelayCommand<object>((param) => rap5());
                }

                return _rap5_Command;
            }
        }

Wszystko mam w ViewModel

2
 
 private RelayCommand<object> _rap5_Command; //Różnica
        public ICommand rap5_Command
        {
            get
            {
                return _rap5_Command ?? (  _rap5_Command = new RelayCommand<object>((param) => rap5()));
            }
        }
1

Czy to tak się robi czy tworzycie nowe klasy dla komend i nie trzymacie ich w ViewModelu

Robi się to tak jak przestawiłeś. Nie ma sensu tworzyć nowej klasy jeśli używasz MVVM Light - ma to sens, gdy samemu implementujesz ICommand. Tutaj mamy już gotową, uniwersalną klasę i możesz jej używać w ViewModelach.
Jeszcze taka uwaga - to co masz w Action od RelayCommand mimo wszystko powinieneś starać się wyrzucać poza ViewModel, do jakiś serwisów ogólnie mówiąc. ViewModel powinien się ograniczać do pobrania danych i przygotowania do ich wyświetlenia, przetwarzanie i operacje na danych to nie jego działka.

0

Dzięki.

A w jaki sposób Wasze ViewModele komunikują się z Modelem? Jak macie to zaimpletowane ?

1

Zależy czym dokładnie jest model.
Ogólnie jak pisałem, głównie przez serwisy, np:

var price = itemService.GetPriceWithDiscount(ItemId, Discount);  //ItemId, Discount - TwoWayBinding z formularza
Price = [konwersja price];
...
string Price { get { return price.ToString("C"); } set { price = value; RaisePropertyChanged("Price"); } }
...
decimal GetPriceWithDiscount(decimal Discount) { return DbContext.Items.FirstOrDefault(item => item.Id = ItemId).Price - Discount; }

Oczywiście to tylko głupi, przykład ale sama idea jest mniej więcej taka.

1

Pomiędzy EF a ViewModel stosuję jeszcze klasę pośredniczącą Model.

 
 private void wplywy_list_Button_Click(object sender, RoutedEventArgs e)
        {
            new View.WplywyList(new ViewModel.WplywyList_VM(new Model.WplywyList_M())).Show();
        }

Wtedy w ViewModel:

 
private Model.WplywyList_M model;

public WplywyList_VM(Model.WplywyList_M model)
{
    this.model=model
}

W model np.

 
public List<MyData.Waluty_ComboBox_p_Result> GetWaluty_CB()
        {
            return waluty_EF.Waluty_ComboBox_p().ToList();
        }

Klasę model stosuję z przyzwyczajenia na zasadzie "bo zawsze była" ale chyba można się spokojnie jej pozbyć.

0

Pogubiłem się nieco , za dużo nowej wiedzy na raz :)

Statyczny model wczytuje zipa, depakuje go i układa dane w List<mojeEntity>. Nie wiem jak przekazać tą listę do ViewModelu nie łamiąc konwencji MVVM ( dokładniej korzystam z MVVM Light ). Natomiast w ViewModelu dałem property <mojeEntity> do którego zbindowałem się w View. Zależy mi na tym, żeby korzystając z dobrodziejstw databindingu i INotifyPropertyChanged z modelu wstrzyknąć dane do property ViewModelu.

1

Mam klasę bazową:

 
public class ViewModel_Base : Info_base, INotifyPropertyChanged

Z której dziedziczą mi wszystkie VM. Dodatkowo klasa ta implementuje mi interface IDataErrorInfo. W tym momencie IDataErrorInfo podłączam do tych VM gdzie go wykorzystuje.

I teraz to już prosto. Danę ciągnę z modelu. Podstawiam pod właściwości MV i na View binduje. Każdą zmianę odświeżam poprzez OnPropertyChanged.
Dodatkowo pod Entity tworzę partial classes i podłączam interface IDataErrorInfo, dzięki temu mogę kontrować poprawność wprowadzonych danych bezpośrednio do tabeli jak i zmiany we właściwościach VM.

 
partial class Wplywy : IDataErrorInfo

Przed każdym zatwierdzeniem (zamknięciem okienka z zapisem) sprawdzam czy Error bezpośrednio z MV lub z obsługiwanej tabeli nie zawiera błędów.

 
 if (this.Error != null || mainEdit.Error != null)

1 użytkowników online, w tym zalogowanych: 0, gości: 1