What i am doing wrong in my ViewModel ?

  • (3 Pages)
  • +
  • 1
  • 2
  • 3

35 Replies - 4866 Views - Last Post: 29 April 2017 - 02:59 AM Rate Topic: -----

#1 JohnRipper  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 27
  • Joined: 28-March 17

What i am doing wrong in my ViewModel ?

Posted 22 April 2017 - 10:21 PM

Hello ! So i posted a program in a forum... and i received a pretty much... huge amount of bad critic about my code... but no one actually helped me to find out what i am doing wrong. Specifically they said that my ViewModel sucks. So.. if someone would like to help me(since i do not have a teacher or something)... i would appreciated. I would like to be told what i am doing wrong in the MVVM so i can improve myself. This program is a Spotify thrird party controller that i made.. which i have the link bellow(i cannot make an attachment, since the server returns an error).

Link: https://www.sendspace.com/file/svefd1

Thank you very much for your time !

Is This A Good Question/Topic? 0
  • +

Replies To: What i am doing wrong in my ViewModel ?

#2 JapanDave  Icon User is offline

  • D.I.C Regular

Reputation: 29
  • View blog
  • Posts: 366
  • Joined: 01-February 16

Re: What i am doing wrong in my ViewModel ?

Posted 22 April 2017 - 10:31 PM

Sorry, I won't open a solution from an un-trusted source. Please post the code that is giving you issues.
Was This Post Helpful? 1
  • +
  • -

#3 andrewsw  Icon User is offline

  • say what now
  • member icon

Reputation: 6410
  • View blog
  • Posts: 25,908
  • Joined: 12-December 12

Re: What i am doing wrong in my ViewModel ?

Posted 23 April 2017 - 12:15 AM

Yes, post relevant code directly here in the forum, between code tags.
Was This Post Helpful? 0
  • +
  • -

#4 JohnRipper  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 27
  • Joined: 28-March 17

Re: What i am doing wrong in my ViewModel ?

Posted 23 April 2017 - 01:31 AM

Ok. Since i cannot edit my topic.. i'll post the code here:

using System;
using System.ComponentModel;
using SpotifyAdvancedController.ViewModel.Command;
using SpotifyAPI.Local;
using SpotifyAPI.Local.Models;
using System.Windows;
using System.Diagnostics;
using System.Speech.Recognition;
using System.IO;

namespace SpotifyAdvancedController.ViewModel.MainWindow
{
    public class MethodsAndProperties : INotifyPropertyChanged
    {
        #region Private and Public Properties
        private SpeechRecognitionEngine SpeechEngine;
        private SpotifyLocalAPI SpotifyAPIInstance;
        private Track CurrentTrack;

        private bool _IsSpotifyMuted = false;
        private string _SongName { get; set; } = "NaN";
        private string _ArtistName { get; set; } = "NaN";
        private string _AlbumName { get; set; } = "NaN";
        private string _Time { get; set; } = "NaN";
        private string _SongStatus { get; set; } = "NaN";
        private string _LastCommand { get; set; } = "NaN";
        private string _ConnectionButtonContent { get; set; } = "Connect";
        private bool _ConnectionButtonEnabled { get; set; } = true;
        private bool _IsVoiceControllerEnabled { get; set; } = false;
        private bool _IsMuteAdsEnabled { get; set; } = false;
        private bool _IsVoiceControllerChecked { get; set; } = false;
        private bool _IsMuteAdsChecked { get; set; } = false;
        private bool _PlayBtnIsEnabled { get; set; } = false;
        private bool _PauseBtnIsEnabled { get; set; } = false;
        private bool _NextBtnIsEnabled { get; set; } = false;
        private bool _PreviousBtnIsEnabled { get; set; } = false;
        private bool _TopMostIsEnabled { get; set; } = false;
        private bool _LastCommandIsEnabled { get; set; } = false;
        private string _SongNameLink { get; set; }
        private string _ArtistNameLink { get; set; }
        private string _AlbumNameLink { get; set; }

        public string SongName { get { return _SongName; } set { _SongName = value; RaisePropertyChanged("SongName"); } }
        public string ArtistName { get { return _ArtistName; } set { _ArtistName = value; RaisePropertyChanged("ArtistName"); } }
        public string AlbumName { get { return _AlbumName; } set { _AlbumName = value; RaisePropertyChanged("AlbumName"); } }
        public string Time { get { return _Time; } set { _Time = value; RaisePropertyChanged("Time"); } }
        public string SongStatus { get { return _SongStatus; } set { _SongStatus = value; RaisePropertyChanged("SongStatus"); } }
        public string LastCommand { get { return _LastCommand; } set { _LastCommand = value; RaisePropertyChanged("LastCommand"); } }
        public string ConnectionButtonContent { get { return _ConnectionButtonContent; } set { _ConnectionButtonContent = value; RaisePropertyChanged("ConnectionButtonContent"); } }
        public bool ConnectionButtonEnabled { get { return _ConnectionButtonEnabled; } set { _ConnectionButtonEnabled = value; RaisePropertyChanged("ConnectionButtonEnabled"); } }
        public bool IsVoiceControllerEnabled { get { return _IsVoiceControllerEnabled; } set { _IsVoiceControllerEnabled = value; RaisePropertyChanged("IsVoiceControllerEnabled"); } }
        public bool IsMuteAdsEnabled { get { return _IsMuteAdsEnabled; } set { _IsMuteAdsEnabled = value; RaisePropertyChanged("IsMuteAdsEnabled"); } }
        public bool IsVoiceControllerChecked { get { return _IsVoiceControllerChecked; } set { if (value == true) SpotifyCommandListener(true); else SpotifyCommandListener(false); _IsVoiceControllerChecked = value; RaisePropertyChanged("IsVoiceControllerChecked"); } }
        public bool IsMuteAdsChecked { get { return _IsMuteAdsChecked; } set { _IsMuteAdsChecked = value; RaisePropertyChanged("IsMuteAdsChecked"); } }
        public bool PlayBtnIsEnabled { get { return _PlayBtnIsEnabled; } set { _PlayBtnIsEnabled = value; RaisePropertyChanged("PlayBtnIsEnabled"); } }
        public bool PauseBtnIsEnabled { get { return _PauseBtnIsEnabled; } set { _PauseBtnIsEnabled = value; RaisePropertyChanged("PauseBtnIsEnabled"); } }
        public bool NextBtnIsEnabled { get { return _NextBtnIsEnabled; } set { _NextBtnIsEnabled = value; RaisePropertyChanged("NextBtnIsEnabled"); } }
        public bool PreviousBtnIsEnabled { get { return _PreviousBtnIsEnabled; } set { _PreviousBtnIsEnabled = value; RaisePropertyChanged("PreviousBtnIsEnabled"); } }
        public bool TopMostIsEnabled { get { return _TopMostIsEnabled; } set { _TopMostIsEnabled = value; RaisePropertyChanged("TopMostIsEnabled"); } }
        public bool LastCommandIsEnabled { get { return _LastCommandIsEnabled; } set { _LastCommandIsEnabled = value; RaisePropertyChanged("LastCommandIsEnabled"); } }
        #endregion

        #region Commands
        public RelayCommand ConnectCommand { get; set; }
        public RelayCommand PlaySongCommand { get; set; }
        public RelayCommand PauseSongCommand { get; set; }
        public RelayCommand NextSongCommand { get; set; }
        public RelayCommand PreviousSongCommand { get; set; }
        public RelayCommand SongNavigateCommand { get; set; }
        public RelayCommand ArtistNavigateCommand { get; set; }
        public RelayCommand AlbumNavigateCommand { get; set; }
        #endregion

        /// <summary>
        /// The ctor(Constructor) of our program
        /// </summary>
        public MethodsAndProperties()
        {
            //initialize the Spotify API
            SpotifyAPIInstance = new SpotifyLocalAPI();
            SpotifyAPIInstance.OnPlayStateChange += SpotifyAPIInstance_OnPlayStateChange;
            SpotifyAPIInstance.ontrackchange += SpotifyAPIInstance_ontrackchange;
            SpotifyAPIInstance.OnTrackTimeChange += SpotifyAPIInstance_OnTrackTimeChange;
            //initialize commands
            ConnectCommand = new RelayCommand(Connect);
            PlaySongCommand = new RelayCommand(PlaySong);
            PauseSongCommand = new RelayCommand(PauseSong);
            NextSongCommand = new RelayCommand(NextSong);
            PreviousSongCommand = new RelayCommand(PreviousSong);
            SongNavigateCommand = new RelayCommand(SongNavigate);
            ArtistNavigateCommand = new RelayCommand(ArtistNavigate);
            AlbumNavigateCommand = new RelayCommand(AlbumNavigate);
            //initialize speech engine
            SpeechEngine = new SpeechRecognitionEngine();
            Choices commands = new Choices();
            commands.Add(new string[] { "play", "stop", "next", "back" });
            GrammarBuilder GramBuilder = new GrammarBuilder();
            GramBuilder.Append(commands);
            Grammar grammar = new Grammar(GramBuilder);
            SpeechEngine.LoadGrammarAsync(grammar);
            SpeechEngine.SetInputToDefaultAudioDevice();
            SpeechEngine.SpeechRecognized += SpeechEngine_SpeechRecognized;
        }

        /// <summary>
        /// ontrackchange event. Occurs when the spotify song changes
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SpotifyAPIInstance_ontrackchange(object sender, TrackChangeEventArgs e)
        {
            CurrentTrack = e.NewTrack;
            UpdateTrack();
        }
        /// <summary>
        /// OnTrackTimeChange. Occurs when the spotify time changes
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SpotifyAPIInstance_OnTrackTimeChange(object sender, TrackTimeChangeEventArgs e)
        {
            Time = $@"{FormatTime(e.TrackTime)}/{FormatTime(CurrentTrack.Length)}";
            if (SongStatus == "NaN")
                SongStatus = "True";
        }
        /// <summary>
        /// OnPlayStateChange. Occurs when the spotify changes state. For example
        /// from play to pause.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SpotifyAPIInstance_OnPlayStateChange(object sender, PlayStateEventArgs e)
        {
            SongStatus = e.Playing.ToString();
        }
        /// <summary>
        /// The SpeechRecognized event. Occurs when someone speeks and the engine
        /// is opened.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SpeechEngine_SpeechRecognized(object sender, SpeechRecognizedEventArgs e)
        {
            switch (e.Result.Text)
            {
                case "play":
                    SpotifyAPIInstance.Play();
                    LastCommand = "Play Song";
                    break;
                case "stop":
                    SpotifyAPIInstance.Pause();
                    LastCommand = "Pause Song";
                    break;
                case "next":
                    SpotifyAPIInstance.Skip();
                    LastCommand = "Next Song";
                    break;
                case "back":
                    SpotifyAPIInstance.Previous();
                    LastCommand = "Previous Song";
                    break;
            }
        }
        /// <summary>
        /// It navigates into the spotify page where the Song is.
        /// </summary>
        /// <param name="obg"></param>
        private void SongNavigate(object obg)
        {
            if(_SongNameLink != null)
                Process.Start(_SongNameLink);
        }
        /// <summary>
        /// It navigates into the spotify page where the Artist is.
        /// </summary>
        /// <param name="obj"></param>
        private void ArtistNavigate(object obj)
        {
            if(_SongNameLink != null)
                Process.Start(_ArtistNameLink);
        }
        /// <summary>
        /// It navigates into the spotify page where the Album is.
        /// </summary>
        /// <param name="obj"></param>
        private void AlbumNavigate(object obj)
        {
            if(_SongNameLink != null)
                Process.Start(_AlbumNameLink);
        }
        /// <summary>
        /// Starts the speech recognition engine in order
        /// to receive commands
        /// </summary>
        /// <param name="Start"></param>
        private void SpotifyCommandListener(bool Start)
        {
            if (Start)
                SpeechEngine.RecognizeAsync(RecognizeMode.Multiple);
            else
                SpeechEngine.RecognizeAsyncStop();
        }
        /// <summary>
        /// Formats the currenttrack time
        /// </summary>
        /// <param name="sec"></param>
        /// <returns></returns>
        private String FormatTime(double sec)
        {
            TimeSpan span = TimeSpan.FromSeconds(sec);
            String secs = span.Seconds.ToString(), mins = span.Minutes.ToString();
            if (secs.Length < 2)
                secs = "0" + secs;
            return mins + ":" + secs;
        }
        /// <summary>
        /// Gets the Spotify Process ID based on it's class name
        /// </summary>
        /// <returns></returns>
        private int GetSpotifyPID()
        {
            Process[] SpotifyProcesses = Process.GetProcessesByName("Spotify");
            foreach (Process Proc in SpotifyProcesses)
            {
                if (VolumeMixerManager.GetApplicationClassName(Proc.Id) == "SpotifyMainWindow")
                {
                    return Proc.Id;
                }
            }
            return 0;
        }
        /// <summary>
        /// This method updates the track information into the UI
        /// </summary>
        private void UpdateTrack()
        {
            if (CurrentTrack.IsAd() && IsMuteAdsEnabled)
            {
                VolumeMixerManager.SetApplicationMute(GetSpotifyPID(), true);
                _IsSpotifyMuted = true;
                SongName = "Advertisement";
                _SongNameLink = null;
                ArtistName = "";
                _ArtistNameLink = null;
                AlbumName = "";
                _AlbumNameLink = null;
                return;
            }
            else
            {
                if (_IsSpotifyMuted)
                    VolumeMixerManager.SetApplicationMute(GetSpotifyPID(), false);
            }

            SongName = CurrentTrack.TrackResource.Name;
            _SongNameLink = CurrentTrack.TrackResource.Uri;
            ArtistName = CurrentTrack.ArtistResource.Name;
            _ArtistNameLink = CurrentTrack.ArtistResource.Uri;
            AlbumName = CurrentTrack.AlbumResource.Name;
            _AlbumNameLink = CurrentTrack.AlbumResource.Uri;
            Time = $@"0:00/{FormatTime(CurrentTrack.Length)}";
        }
        /// <summary>
        /// The play song command
        /// </summary>
        /// <param name="obj"></param>
        private void PlaySong(object obj)
        {
            SpotifyAPIInstance.Play();
            LastCommand = "Play Song";
        }
        /// <summary>
        /// The pause song command
        /// </summary>
        /// <param name="obj"></param>
        private void PauseSong(object obj)
        {
            SpotifyAPIInstance.Pause();
            LastCommand = "Pause Song";
        }
        /// <summary>
        /// The next song command
        /// </summary>
        /// <param name="obj"></param>
        private void NextSong(object obj)
        {
            SpotifyAPIInstance.Skip();
            LastCommand = "Next Song";
        }
        /// <summary>
        /// The previous song command
        /// </summary>
        /// <param name="obj"></param>
        private void PreviousSong(object obj)
        {
            SpotifyAPIInstance.Previous();
            LastCommand = "Previous Song";
        }
        /// <summary>
        /// This method connects into the Spotify client
        /// </summary>
        /// <param name="obj"></param>
        private void Connect(object obj)
        {
            bool successful = false;
            if (!SpotifyLocalAPI.IsSpotifyRunning())
            {
               MessageBoxResult Result = MessageBox.Show("Spotify isn't running! Would you like to open it for you ?", "Spotify isn't running", MessageBoxButton.YesNo, MessageBoxImage.Exclamation);
                
                if(Result == MessageBoxResult.Yes)
                {
                    string SpotifyPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Spotify", "Spotify.exe");
                    if (File.Exists(SpotifyPath))
                    {
                        Process.Start(SpotifyPath);
                        MessageBox.Show("Spotify succesfully started. Please re-connect !", "Spotify Started", MessageBoxButton.OK, MessageBoxImage.Information);
                    }
                    else
                    {
                        MessageBox.Show("Spotify isn't installed in the default directory. Starting spotify failed. Please open it manual or install spotify on the default directory!!", "Operation Failed", MessageBoxButton.OK, MessageBoxImage.Error);
                    }
                    return;
                }
                else
                {
                    return;
                }
            }
            if (!SpotifyLocalAPI.IsSpotifyWebHelperRunning())
            {
                MessageBox.Show("SpotifyWebHelper isn't running! Please re-start Spotify !!");
                return;
            }
            try
            {
                successful = SpotifyAPIInstance.Connect();
            }
            catch (Exception)
            {
              MessageBoxResult Result = MessageBox.Show("Connection failed. Please check your internet connection. Try to re-connect ?", "Fatal Error", MessageBoxButton.YesNo, MessageBoxImage.Error);
                if(Result == MessageBoxResult.Yes)
                {
                    Connect(null);
                    return;
                }
                else
                {
                    return;
                }
            }
            if (successful)
            {
                ConnectionButtonContent = "Connection to Spotify Established";
                ConnectionButtonEnabled = false;
                SpotifyAPIInstance.ListenForEvents = true;

                ConnectionButtonEnabled = false;
                IsVoiceControllerEnabled = false;
                IsMuteAdsEnabled = true;
                IsVoiceControllerEnabled = true;
                PlayBtnIsEnabled = true;
                PauseBtnIsEnabled = true;
                NextBtnIsEnabled = true;
                PreviousBtnIsEnabled = true;
                TopMostIsEnabled = true;
                LastCommandIsEnabled = true;
                StatusResponse status = SpotifyAPIInstance.GetStatus();
                CurrentTrack = status.Track;
                UpdateTrack();
            }
            else
            {
                MessageBoxResult Result = MessageBox.Show("Couldn't connect to the spotify client. Retry?", "Spotify", MessageBoxButton.YesNo);
                if (Result == MessageBoxResult.Yes)
                    Connect(null);
            }
        }

        #region PropertyChangedEventHandler and RaisePropertyChanged method
        public event PropertyChangedEventHandler PropertyChanged;

        private void RaisePropertyChanged(string property)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(property));
            }
        }
        #endregion
    }
}



P.S Sorry about the bad format of the code, but that's a forum-problem. Just copy+paste it in a .cs file or whatever for better reading :)
Was This Post Helpful? 0
  • +
  • -

#5 JapanDave  Icon User is offline

  • D.I.C Regular

Reputation: 29
  • View blog
  • Posts: 366
  • Joined: 01-February 16

Re: What i am doing wrong in my ViewModel ?

Posted 23 April 2017 - 01:31 AM

Is all those properties used on a single tab view?

Anyway, what is the issue?

This post has been edited by JapanDave: 23 April 2017 - 01:32 AM

Was This Post Helpful? 0
  • +
  • -

#6 JohnRipper  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 27
  • Joined: 28-March 17

Re: What i am doing wrong in my ViewModel ?

Posted 23 April 2017 - 01:50 AM

View PostJapanDave, on 23 April 2017 - 08:31 AM, said:

Is all those properties used on a single tab view?

Anyway, what is the issue?

Yep. Their all binded in a window. There isn't a specific issue... the thing is that whenever i post this code coders/programmers say that (i quote): "You ve'missed the whole MVVM logic".. but no one actually help me... that's why i am asking for your opinion here guys... because you have helped me whenever i needed any opinion/help.
Was This Post Helpful? 0
  • +
  • -

#7 JapanDave  Icon User is offline

  • D.I.C Regular

Reputation: 29
  • View blog
  • Posts: 366
  • Joined: 01-February 16

Re: What i am doing wrong in my ViewModel ?

Posted 23 April 2017 - 02:11 AM

I don't know exactly what other people are saying but, this from what I can see. It seems that you have just lumped everything into the ViewModel, eg I don't have RaisePropertyChanged method in my ViewModels, it is a base wrapper class for the related viewModel wrappers. You need to break the classes up. I also think people probably have looked at the name of the class MethodsAndProperties and made a judgement there too. You should probably name it it something different that relates to the view, ie ConnectionViewModel (this is just an example, by no means name it this.).

Why do you have a folder named MainWindow?

This post has been edited by JapanDave: 23 April 2017 - 02:32 AM

Was This Post Helpful? 1
  • +
  • -

#8 JohnRipper  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 27
  • Joined: 28-March 17

Re: What i am doing wrong in my ViewModel ?

Posted 23 April 2017 - 03:11 AM

View PostJapanDave, on 23 April 2017 - 09:11 AM, said:

I don't know exactly what other people are saying but, this from what I can see. It seems that you have just lumped everything into the ViewModel, eg I don't have RaisePropertyChanged method in my ViewModels, it is a base wrapper class for the related viewModel wrappers. You need to break the classes up. I also think people probably have looked at the name of the class MethodsAndProperties and made a judgement there too. You should probably name it it something different that relates to the view, ie ConnectionViewModel (this is just an example, by no means name it this.).

Why do you have a folder named MainWindow?


Ok. I'll make these changes then. But what about my code ? Should i make any changes to it ? Now... about the class name.. should i name it: MainWindowViewModel for example ? Is this a decent name for a main window viewmodel class ?

I am a creature of habit. When i have alot of windows... i seperate the viewmodels of each form on a different folder. Beside the class... i put inside classes that i need only in this window. That way i know every class where it belongs. I think that this help people when they read my code.Is this a bad practice ?
Was This Post Helpful? 0
  • +
  • -

#9 tlhIn`toq  Icon User is offline

  • Xamarin Cert. Dev.
  • member icon

Reputation: 6507
  • View blog
  • Posts: 14,379
  • Joined: 02-June 10

Re: What i am doing wrong in my ViewModel ?

Posted 23 April 2017 - 07:54 AM

A big part of what you missed in the concept that the ViewModel doesn't know anything about the View. There shouldn't be anything in the ViewModel that is specific to a View... BECAUSE a ViewModel can be binded to 0 or more Views. That means there may not be any View, or there could be 10 views.

You have bunches of properties that exist solely for the purpose of controlling UI elements, such as:
        private bool _ConnectionButtonEnabled { get; set; } = true;

From an MVVM perspective that's wrong.

ViewModels don't care about UI and shouldn't have anything that is UI specific.

You want to shift your perspective. Stop trying to micro-manage the UI. Don't try to control (enable/disable) UI elements. Instead, stop and think about *why* a control would be enabled.

For example: Don't enable/disable the [SAVE] button. You would want the [SAVE] button enabled when the data object is dirty (has unsaved changes). Thus your object would have an IsDirty property. That property doesn't exist for the sole purpose of controlling UI, but can be bound to 15 UI objects - that thus when the object IsDirty all those things become enabled.

Instead of doing this in a method SongName = CurrentTrack.TrackResource.Name; just bind to that property on that object:
<Label Text = "{Binding CurrentTrack.TrackResource.Name}"

Now just changing the select track automatically updates the UI - No methods.

If 10 object should be visible when the mode is SUPERVISOR, you don't manage them all... Your object just has a *mode* property and your 4 different views bind to the mode of the data context object.

Next:
You have a method for FormatTime. You shouldn't need that. Time is time. Keep time in an object. Instead of a method for formatting this, you just want to string.format the display in the UI. What you have here would require 10 different methods if you needed 10 different ways to display the time. Since formatting is strictly a UI need for human eyes, it belongs at a UI layer: In the XAML.

Next:
/// This method updates the track information into the UI
There's too much of this in your code. You shouldn't ever need methods that exist solely to update UI. Again, the ViewModel might be binded to 10 different things. So *which* UI would you be updating for?

Next:
Your Connect() method does far more than just connect. That violates the single responsibility concept. Connect needs to JUST connect. It is not responsible for UI, it doesn't show message boxes. It tries to connect and returns a result. Period. UI can bind to the result, or the method calling connect can then react to the success or fail of the attempt.

This post has been edited by tlhIn`toq: 23 April 2017 - 08:02 AM

Was This Post Helpful? 1
  • +
  • -

#10 JohnRipper  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 27
  • Joined: 28-March 17

Re: What i am doing wrong in my ViewModel ?

Posted 23 April 2017 - 08:57 AM

Ok... so here it comes the question... ViewModel isn't supposed to "connect" the model and the view ? This is what everyone is saying. I interpret that... as that i should control the View from the ViewModel. And if that's wrong... where i should put all these properties and the UI specific stuff ?

Now.. as for the other... it seems more about "logical" errors that i should fix... and not code errors. I'll try to improve these one.

This post has been edited by tlhIn`toq: 23 April 2017 - 09:26 AM
Reason for edit:: No need to quote the entire previous post

Was This Post Helpful? 0
  • +
  • -

#11 JohnRipper  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 27
  • Joined: 28-March 17

Re: What i am doing wrong in my ViewModel ?

Posted 23 April 2017 - 09:02 AM

P.S Now that i am re-reading for the third time what you saying... i think that you mean that i should continue manage the View from the ViewModel.. but i should be more "generic" about my properties... and not have "SaveBtnEnabled" properties and e.t.c. because if you want to use the ViewModel on another UI for example.. in another platform... it's not gonna be ceertain that it will have the exact same UI elements as mine did... right ? Tell me if i understood correctly what you said. Also i should give better names in my methods. Give me an example... how you would call the "Connect" method ? I am trying to understand how a pro programmer thinks... i am trying to understand the "logic" :)
Was This Post Helpful? 0
  • +
  • -

#12 tlhIn`toq  Icon User is offline

  • Xamarin Cert. Dev.
  • member icon

Reputation: 6507
  • View blog
  • Posts: 14,379
  • Joined: 02-June 10

Re: What i am doing wrong in my ViewModel ?

Posted 23 April 2017 - 09:25 AM

>

Quote

i think that you mean that i should continue manage the View from the ViewModel..


No. This is the perspective you need to change. (and it sounds like you're hearing this elsewhere) -
>

Quote

ViewModel isn't supposed to "connect" the model and the view ? This is what everyone is saying.


I'm saying exactly the opposite: Stop trying to manage the View AT ALL. That very early concept is then forcing how you code and taking you down a bad direction.
Let the view manage itself... based on bindings to the object state.

Try thinking this way...
Assume the ViewModel isn't binded to ANY view. No view when you make the view model. It just has properties and methods to do IT'S job and its job only, which is to get work done. So no properties or methods that are UI related, exist for managing any UI, etc.

As a rule methods names are verbs, properties are things and thus nouns. Methods that are enacted by events/commands usually are prefixed with 'On'...
OnSaveCommand... OnPlaySongCommand
Was This Post Helpful? 1
  • +
  • -

#13 JohnRipper  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 27
  • Joined: 28-March 17

Re: What i am doing wrong in my ViewModel ?

Posted 23 April 2017 - 10:23 AM

View PosttlhIn`toq, on 23 April 2017 - 04:25 PM, said:

So no properties or methods that are UI related, exist for managing any UI, etc.


It's relative easy to create non-UI related methods... but properties it's kinda difficult. How i am gonna enable and disable components that some time needs to be disabled or enabled ?? I should do this:

Quote

For example: Don't enable/disable the [SAVE] button. You would want the [SAVE] button enabled when the data object is dirty (has unsaved changes). Thus your object would have an IsDirty property. That property doesn't exist for the sole purpose of controlling UI, but can be bound to 15 UI objects - that thus when the object IsDirty all those things become enabled.
?? And if Yes... what happens if i need to have an object enabled when an internal operation(when i fetch some data inside a ViewModel method for example) occurs ? How i am gonna control a component in the UI ?
Was This Post Helpful? 0
  • +
  • -

#14 Skydiver  Icon User is offline

  • Code herder
  • member icon

Reputation: 5928
  • View blog
  • Posts: 20,267
  • Joined: 05-May 12

Re: What i am doing wrong in my ViewModel ?

Posted 23 April 2017 - 01:52 PM

That is where data triggers and converters come into the picture.
Was This Post Helpful? 1
  • +
  • -

#15 tlhIn`toq  Icon User is offline

  • Xamarin Cert. Dev.
  • member icon

Reputation: 6507
  • View blog
  • Posts: 14,379
  • Joined: 02-June 10

Re: What i am doing wrong in my ViewModel ?

Posted 23 April 2017 - 02:11 PM

Quote

How i am gonna control a component in the UI ?


Again, you don't. Stop trying to control it. Let it control itself... based on the state of the data object.

The Play button enables itself when the SelectedSong is not null.
The Save button enables itself when the SelectedSong.Metadata has been changed (genre from Rock to Pop).
The Color of the player background changes itself based on the SelectedSong.Metadata.Genre

Stop trying to control the UI from code. At most code that is not part of your ViewModel, such as a converter, exists for the convenience of and use by the UI - that is code that exists for the UI, not code that manages the UI.

Take a look at my series on Xamarin (which is another XAML/MVVM technology - a sibling/peer to WPF). I do a whole long thing about how making the shift to MVVM design pattern is a big paradigm shift for most developers. Shifting your thinking to it takes a little time and practice. After which you wouldn't dream of coding any other way.
https://redpillxamar...to-this-series/
Was This Post Helpful? 1
  • +
  • -

  • (3 Pages)
  • +
  • 1
  • 2
  • 3