MVVM and EF

0

Witam wszystkich.
Wzorca mvvm dopiero się uczę chociaż WPF już trochę znam. Mój problem polega na tym że nie wiem czy dobrze się 'zabieram' do tego ;) Tworzę małą aplikację w technologi WPF i wykorzystuję wzorzec mvvm, wykorzystuję też technologię Entity Framework.

Mam klasę Klient wygenerowaną przez EF.

    
    public partial class W_Klient
    {
        public W_Klient()
        {
            this.W_WorkHistory = new HashSet<W_WorkHistory>();
        }
    
        public int k_Id { get; set; }
        public string K_Nazwa { get; set; }
        public string k_Miejscowosc { get; set; }
        public string k_ulica { get; set; }
        public string k_NrDomu { get; set; }
        public string K_NrLokalu { get; set; }
        public string k_NrTelefonu { get; set; }
        public string k_Email { get; set; }
    
        public virtual ICollection<W_WorkHistory> W_WorkHistory { get; set; }
    }

Oraz ViewModel

namespace WorkerApp.ViewModels
{
    public class CustomerViewModel : ModelBase, IDataErrorInfo
    {
        private DelegateCommand saveCommand { get; set; }
        private W_Klient _customer;
        public W_Klient Customer 
        { 
            get {return _customer; }
            set
            {
                _customer = value;
                OnPropertyChange("Customer");
            }
        }
        private bool _isValidating;
        public bool IsValidating
        {
            get { return _isValidating; }
            set
            {
                _isValidating = value;
                OnPropertyChange("IsValidating");
                OnPropertyChange("Customer");
            }
        }

        public CustomerViewModel(W_Klient _customer)
        {
            if (_customer == null)
            {
                Customer = new W_Klient();
            }
            else
            {
                Customer = _customer;
            }
            saveCommand = new DelegateCommand(SaveAction, CanSave);
        }

        public ICommand SaveCommand
        {
            get
            {
                if (saveCommand == null)
                {
                    saveCommand = new DelegateCommand(SaveAction, CanSave);
                }
                return saveCommand;
            }
        }

        private bool CanSave(object obj)
        {
            return true;
        }

        private void SaveAction(object obj)
        {
            IsValidating = true;
            if (ValidateNazwa()==null && ValidateTele()==null)
            {

            }
        }

        public string Error
        {
            get { throw new NotImplementedException(); }
        }

        public string this[string columnName]
        {
            get
            {
                if (!IsValidating) return null;
                string result = string.Empty;
                switch (columnName)
                {
                    case "k_NrTelefonu": if (string.IsNullOrWhiteSpace(Customer.k_NrTelefonu)) result = "Telefon nie może być pusty."; ; break;
                }
                return result;
            }
        }
    }
}

View:

<Window x:Class="WorkerApp.Views.CustomerWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="CustomerWindow" Name="WindowCustomer" Height="400" Width="690" AllowsTransparency="True" WindowStyle="None" WindowStartupLocation="CenterScreen">
    <Window.Resources>
        <ControlTemplate x:Key="errorTemplate">
            <DockPanel LastChildFill="true">
                <Border Background="OrangeRed" DockPanel.Dock="right"
                    Margin="3,0,0,0" Width="20" Height="20" CornerRadius="5"
                    ToolTip="{Binding ElementName=adoner,
                        Path=AdornedElement.(Validation.Errors)[0].ErrorContent}">
                    <TextBlock Text="!" VerticalAlignment="center" HorizontalAlignment="center"
                           FontWeight="Bold" Foreground="white" />
                </Border>
                <AdornedElementPlaceholder Name="adoner" VerticalAlignment="Center">
                    <Border BorderBrush="OrangeRed" BorderThickness="1" />
                </AdornedElementPlaceholder>
            </DockPanel>
        </ControlTemplate>
        <Style x:Key="textBoxError" TargetType="TextBox">
            <Style.Triggers>
                <Trigger Property="Validation.HasError" Value="true">
                    <Setter Property="ToolTip"
                        Value="{Binding RelativeSource={x:Static RelativeSource.Self},
                        Path=(Validation.Errors)[0].ErrorContent}"/>
                </Trigger>
            </Style.Triggers>
        </Style>
    </Window.Resources>
	<Grid>
		<Label Content="Nazwa:" Grid.Column="1" Grid.Row="1"/>
		<Label Content="Miejscowość:" Grid.Row="3" Grid.Column="1"/>
		<Label Content="Ulica:" Grid.Row="3" Grid.Column="4"/>
		<Label Content="Nr domu:" Grid.Row="5" Grid.Column="1"/>
		<Label Content="Nr lokalu:" Grid.Row="5" Grid.Column="4"/>
		<Label Content="Nr tele:" Grid.Row="7" Grid.Column="1"/>
		<Label Content="E-mail:" Grid.Row="7" Grid.Column="4"/>
		<TextBox Grid.Row="1" Grid.Column="2" Grid.ColumnSpan="4" Text="{Binding Customer.K_Nazwa, UpdateSourceTrigger=LostFocus, ValidatesOnDataErrors=True, NotifyOnValidationError=True}" Validation.ErrorTemplate="{StaticResource errorTemplate}" Style="{StaticResource textBoxError}"/>
		<TextBox Grid.Row="3" Grid.Column="2" Text="{Binding Customer.k_Miejscowosc}"/>
		<TextBox Grid.Row="3" Grid.Column="5" Text="{Binding Customer.k_ulica}"/>
		<TextBox Grid.Row="5" Grid.Column="2" Text="{Binding Customer.k_NrDomu}"/>
		<TextBox Grid.Row="5" Grid.Column="5" Text="{Binding Customer.K_NrLokalu}"/>
		<TextBox Grid.Row="7" Grid.Column="2" Text="{Binding Customer.k_NrTelefonu, UpdateSourceTrigger=LostFocus, ValidatesOnDataErrors=True, NotifyOnValidationError=True}" Validation.ErrorTemplate="{StaticResource errorTemplate}" Style="{StaticResource textBoxError}"/>
		<TextBox Grid.Row="7" Grid.Column="5" Text="{Binding Customer.k_Email}"/>
		<Button Content="Zapisz" Grid.Column="1" Command="{Binding SaveCommand}"  Grid.Row="1" Style="{StaticResource ButtonStyleTrans}" />
    </Grid>
</Window>

Główny problem polega na tym że nie wiem czy poprawnie wykonuję bindowanie w tym momencie jest tak Text="{Binding Customer.K_NrLokalu}"/> a nie wiem czy nie powinienem zrobić tak Text="{Binding K_NrTele}"/> a w viewmodelu nie powinno byc tak

	public string K_NrTele
        { 
            get {return Customer.k_NrTelefonu; }
            set
            {
                Customer.k_NrTelefonu = value;
            }
        }

Nie wiem która z tych opcji jest poprawna. Druga problem polega na tym że w tym momencie nie działa walidacja danych nie wiem czemu :( bardzo proszę o pomoc i wyrozumiałość :)

0

Dawno WPFa nie używałem, ale:

 
public W_Klient Customer 
        { 
            get {return _customer; }
            set
            {
                _customer = value;
                OnPropertyChange("Customer");
            }
        }

W tym przypadku nie ma zdarzenia z informacją jaka właściwość została zmieniona, możesz sprawdzić czy idzie informacja o zmianie właściwości "Customer", gdy zmienisz jakąś właściowość należącą do modelu, ale wydaje mi się że też nie będzie.
Najlepiej więc tak jak piszesz wystawić w ViewModelu poszczególne właściwości

Interfejs IDataErrorInfo możesz spróbować zaimplementować w Modelu zamiast ViewModelu, http://tomasz-net.blogspot.com/search/label/INotifyErrorInfo .
Możesz też sprawdzić debuggerem co wpada do

 switch (columnName)

Możliwe, że nic albo "Customer".
Niepotrzebne też będzie "IsValidating", walidacja w tym przypadku powinna działać z automatu po zmianie wartości właściwości.

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