【问题标题】:Is it possible to execute ICommand on page load?是否可以在页面加载时执行 ICommand?
【发布时间】:2020-03-23 13:32:14
【问题描述】:

我的视图模型中有一个 Icommand,如下所示:

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

我将此命令绑定到一个按钮,以搜索某个用户的薪水历史记录,以便它输出信息,效果很好。但是,我也想在加载时以最近的薪水执行它信息(当月)。 Icommand 可以吗?如果没有,我可以通过哪些其他方式在加载时实现此功能。 *注意:变量都存在于与 SalaryCommand 相同的视图模型中,而不是 FetchSalary() 的类中;

我尝试在主工资页面中执行此操作,但没有成功:

        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);
        }

这是适用于按钮的 FetchSalary() 函数

         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);
        }

【问题讨论】:

  • 命令内的代码可以提取到方法中,您可以在命令内和页面加载期间调用此方法。
  • 这能回答你的问题吗? Programmatically raise a command
  • 我尝试直接从类的页面调用 FetchSalary,但这不会更新视图模型中的值,因此它不会显示在视图中。你是这个意思吗?如果不能,请提供一个例子吗?
  • 我认为需要提供一个例子。向我们展示您的一些代码,也许我们可以告诉您为什么您的 FetchSalary 没有按预期执行。 Command 对象不是这里的问题。
  • 您在哪里将数据绑定到您的视图模型?

标签: c# xamarin mvvm icommand


【解决方案1】:

在 Fetching() 中,您创建了一个视图模型,但您没有将它传递给 this.DataContext,因此当“svm”更新时,视图并不关心。

只需将您的命令提取到一个方法中并在您的构造函数中调用它。

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

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

【讨论】:

  • 所以我包含一个 this.DataContext = new SalaryViewModel(); ?
  • @BelleKassouf:不。照他说的做。将_apiServices.FetchSalary(this) 放入一个新方法中,并在您的构造函数中调用它,如上所示。
  • 我按照上图中的说明做了,但是当我在 Fetching() 中调用该方法时,视图中没有任何变化。
  • 从您的视图模型构造函数中调用它。您在哪里将视图模型绑定到页面 dataContext。
【解决方案2】:

一旦页面加载完毕,您可以通过处理Loaded 事件执行相同的命令:

public SalaryPage()
{
    InitializeComponent();
    Loaded += (s, e) =>
    {
        SalaryCommand.Execute(null);
    };
}

【讨论】:

  • 在致电Execute 之前检查CanExecute 是个好主意。
  • 鉴于问题中的示例代码,CanExecute 将始终返回true
  • Loaded 仅在 android 中使用,我正在使用 xamarin 跨平台工作,恐怕它可能无法在 iOS 上运行,因为 Loaded 使用的是 Android.Content,对吧?
  • @BelleKassouf:你应该更好地标记你的问题。
  • Xamarin.Forms 有一个 OnAppearing 事件。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-01-09
  • 2013-09-12
  • 2021-04-01
  • 2019-12-14
  • 1970-01-01
  • 1970-01-01
  • 2012-08-04
相关资源
最近更新 更多