0

I have an Icommand in my view model as shown below:

 public ICommand SalaryCommand
        {
            get
            {
                return new Command(async () =>
                {
                        await _apiServices.FetchSalary(this);
                });
            }
        }

I have this command bind to a button, to search for the salary history of a certain user so that it'll output the information, which works perfectly.However, I also want to execute it on load with the most recent salary information (current month). is it possible with the Icommand? if not, what other ways can I implement this function on load. *note: the variables are all existent in the same view model as the SalaryCommand and not in the class of FetchSalary();

I tried doing this in the main salary page but it didn't work:

        public SalaryPage()
        {
            InitializeComponent();
            Fetching();
        }
        private async void Fetching()
        {
            ApiServices _apiServices = new ApiServices();
            SalaryViewModel svm = new SalaryViewModel();
            string year = DateTime.Now.Year.ToString();
            string month = DateTime.Now.Month.ToString();
            await _apiServices.FetchSalary(svm);
        }

and here is the FetchSalary() function which worked for the button

         public async Task FetchSalary(SalaryViewModel svm)
        {
            Debug.WriteLine("Welcome to the fetch salary method");
            var keyValues = new List<KeyValuePair<string, string>>
            {
                new KeyValuePair<string, string>("UserID",App._username),
                new KeyValuePair<string, string>("Year",svm.dSYear),
                new KeyValuePair<string, string>("Month",svm.dSMonth)
            };
            var request = new HttpRequestMessage(HttpMethod.Post, "somelink");

            request.Content = new FormUrlEncodedContent(keyValues);

            var client = new HttpClient();
            var response = await client.SendAsync(request);

            var content = await response.Content.ReadAsStringAsync();
            Debug.WriteLine(content);


            start = content.IndexOf("Sal_Trsp") + "Sal_Trsp".Length;
            end = content.IndexOf("Sal_NssfMedPay") - start;
            string transportation = content.Substring(start, end);
            svm.sTransportation = "Transportation: " + simplify(transportation);


            start = content.IndexOf("Sal_Date_Year") + "Sal_Date_Year".Length;
            end = content.IndexOf("Sal_Date_Month") - start;
            string yyear = content.Substring(start, end);
            svm.sYear = "Year: " + simplify(yyear);

            start = content.IndexOf("Sal_Date_Month") + "Sal_Date_Month".Length;
            end = content.IndexOf("}") - start;
            string mmonth = content.Substring(start, end);
            svm.sMonth = "Month: " + simplify(mmonth);

            start = content.IndexOf("Sal_NetPaid") + "Sal_NetPaid".Length;
            end = content.IndexOf("Sal_users_FK") - start;
            string retString = content.Substring(start, end);
            svm.sNetPay = "Net Paid: " + simplify(retString);
            Debug.WriteLine(svm.sNetPay);
        }

B.K
  • 17
  • 7
  • The code inside command can be extracted into method and you can call this method from within command and during page load. – Sinatr Mar 23 '20 at 13:33
  • Does this answer your question? [Programmatically raise a command](https://stackoverflow.com/questions/3520713/programmatically-raise-a-command) – Sinatr Mar 23 '20 at 13:34
  • I tried calling FetchSalary directly from the page of the class, but this does not update the values in the view model, so it does not show in the view. is that what you mean? if not can you please provide an example? – B.K Mar 23 '20 at 13:36
  • I think *you* need to provide an example. Show us some of your code and maybe we can tell you why your FetchSalary isn't executing as intended. The Command object isn't the problem here. – Robert Harvey Mar 23 '20 at 13:37
  • Where are you binding the data to your View Model? – Robert Harvey Mar 23 '20 at 13:48
  • this is the whole code for FetchSalary, am I missing a bind to the view model? isnt the svm.variable the bind? sorry, im new to this. – B.K Mar 23 '20 at 13:49
  • @RobertHarvey I have edited the question, I hope it's clearer. – B.K Mar 23 '20 at 14:05
  • Does it work if you click the button? – Robert Harvey Mar 23 '20 at 14:13
  • @RobertHarvey Yes the binding of the SalaryCommand with the button in the view works just fine. – B.K Mar 23 '20 at 14:14
  • Well, sure, but does it produce the result you expect? Does it display the proper salary, or whatever? – Robert Harvey Mar 23 '20 at 14:20
  • @RobertHarvey yes, all needed variables are displayed from the database to the view just the way I want it. I have a public event PropertyChangedEventHandler PropertyChanged; in the view model that will refresh the values on button clicked. – B.K Mar 23 '20 at 14:22

2 Answers2

1

Inside Fetching() you create a view model but you haven't passed it to this.DataContext, so when "svm" is updated the View doesn't care.

Just extract your command into a method and call it in your constructor.

public SalaryViewModel() {
       Task.Run(async () => await FetchingAsync());
}

public ICommand SalaryCommand
        {
            get
            {
                return new Command(async () => await FetchingAsync());
            }
        }
private async Task FetchingAsync() {
       _apiServices.FetchSalary(this);
}
  • so i inlcude a this.DataContext = new SalaryViewModel(); ? – B.K Mar 23 '20 at 14:28
  • @BelleKassouf: No. Do what he says. Put `_apiServices.FetchSalary(this)` into a new method, and call it in your constructor, as illustrated above. – Robert Harvey Mar 23 '20 at 14:40
  • I did as told in the above illustration, but when i called the method in the Fetching(), nothing changes in the view. – B.K Mar 23 '20 at 15:02
  • Call it from your view model constructor. Where are you binding the view model to the page dataContext. – StephenHealey86 Mar 23 '20 at 15:10
1

You may execute the very same command once the page has been loaded by handling the Loaded event:

public SalaryPage()
{
    InitializeComponent();
    Loaded += (s, e) =>
    {
        SalaryCommand.Execute(null);
    };
}
mm8
  • 163,881
  • 10
  • 57
  • 88