命令参数始终返回 null - Xamarin Forms

时间:2021-05-01 17:25:07

标签: forms xamarin parameters null command

我正在尝试制作一个应用程序,将主题和任务保存在本地数据库中。添加新任务时我卡住了。我为 NewTaskPage 做了一个命令,它总是返回一个空值,而它应该返回一个任务对象(STask)。

我找不到任何有用的东西。代码有什么问题?

XAML 代码 (NewTaskPage):

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="MyApp.View.ShellPages.NewTaskPage"
             Shell.FlyoutBehavior="Disabled">
    <StackLayout x:Name="newTaskStackLayout">
        <Label FontSize="Large" Text="Add a new task"/>
        <Entry Placeholder="Name" Text="{Binding Name, Mode=TwoWay}"/>
        <Picker ItemsSource="{Binding SubjectList}" ItemDisplayBinding="{Binding Name}"
                SelectedIndex="{Binding Index, Mode=TwoWay}"/>
        <CheckBox IsChecked="{Binding IsDeadline, Mode=TwoWay}" />
        <DatePicker Date="{Binding Date, Mode=TwoWay}" IsEnabled="{Binding DateEnabled}"/>
        <Button Text="Save" Command="{Binding NewTaskCommand}" 
                CommandParameter="{Binding Stask}"/>
    </StackLayout>
</ContentPage>

视图模型:

namespace MyApp.ViewModel
{
    public class NewTaskViewModel : INotifyPropertyChanged
    {
        private STask stask;
        public STask Stask
        {
            get { return stask; }
            set
            {
                stask = value;
                OnPropertyChanged(nameof(Stask));
            }
        }
        public NewTaskCommand NewTaskCommand { get; set; }
        public List<Subject> SubjectList { get; set; }
        public NewTaskViewModel()
        {
            Stask = new STask();
            SubjectList = new List<Subject>();
            InitializeSubjectList();
            NewTaskCommand = new NewTaskCommand(this);
        }

        public async void InitializeSubjectList()
        {
            var subjects = await SubjectServices.GetSubjects();
            SubjectList.Clear();
            foreach (var subject in subjects)
                SubjectList.Add(subject);
        }

        private DateTime date;
        public DateTime Date
        {
            get { return date; }
            set
            {
                date = value;
                Stask = new STask()
                {
                    Name = this.Name,
                    IsDeadline = this.IsDeadline,
                    DeadLine = this.Date,
                    SubjectID = SubjectList[this.Index].ID
                };
                OnPropertyChanged(nameof(Date));
            }
        }

        private bool isdeadline;
        public bool IsDeadline
        {
            get { return isdeadline; }
            set
            {
                isdeadline = value;
                Stask = new STask()
                {
                    Name = this.Name,
                    IsDeadline = this.IsDeadline,
                    DeadLine = this.Date,
                    SubjectID = SubjectList[this.Index].ID
                };
                DateEnabled = value;
                OnPropertyChanged(nameof(IsDeadline));
            }
        }

        private bool dateenabled;
        public bool DateEnabled
        {
            get { return dateenabled; }
            set
            {
                dateenabled = value;
                Stask = new STask()
                {
                    Name = this.Name,
                    IsDeadline = this.IsDeadline,
                    DeadLine = this.Date,
                    SubjectID = SubjectList[this.Index].ID
                };
                OnPropertyChanged(nameof(DateEnabled));
            }
        }

        private string name;
        public string Name
        {
            get { return name; }
            set
            {
                name = value;
                Stask = new STask()
                {
                    Name = this.Name,
                    IsDeadline = this.IsDeadline,
                    DeadLine = this.Date,
                    SubjectID = SubjectList[this.Index].ID
                };
                OnPropertyChanged(nameof(Name));
            }
        }

        private int index;
        public int Index
        {
            get { return index; }
            set
            {
                index = value;
                Stask = new STask()
                {
                    Name = this.Name,
                    IsDeadline = this.IsDeadline,
                    DeadLine = this.Date,
                    SubjectID = SubjectList[this.Index].ID
                };
                OnPropertyChanged(nameof(Index));
            }
        }


        public event PropertyChangedEventHandler PropertyChanged;
        public void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged == null)
                return;

            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }

        public async void SaveTask(STask s)
        {
            int rows = 0;
            rows = await STaskServices.AddTask(s);
            if (rows > 0)
                await App.Current.MainPage.DisplayAlert("Debug", $"Task successfully saved!\nName: {s.Name}", "Ok");
            else
                await App.Current.MainPage.DisplayAlert("Error", "An error has occured while saving the task!", "Ok");
        }
    }
}

NewTaskCommand:(用于 NewTaskViewModel)

namespace MyApp.ViewModel.Commands
{
    public class NewTaskCommand : ICommand
    {
        public NewTaskViewModel NewTaskViewModel;
        public NewTaskCommand(NewTaskViewModel ntvm)
        {
            this.NewTaskViewModel = ntvm;
        }
        public event EventHandler CanExecuteChanged;

        public bool CanExecute(object parameter)
        {
            //parameter is null
            string param = parameter as string;
            var task = (STask)parameter; 
            if (task == null) //even with this, i still have an exception
                return false;

            if(string.IsNullOrEmpty(task.Name)) 
                return false;

            return true;
        }

        public void Execute(object parameter)
        {
            STask s = parameter as STask;
            NewTaskViewModel.SaveTask(s);
        }
    }
}

我感谢任何形式的帮助!

2 个答案:

答案 0 :(得分:0)

我找到了解决办法。我把它放在我的 XAML 代码中:

xmlns:viewmodel="clr-namespace:MyApp.ViewModel" 
         x:DataType="viewmodel:NewTaskViewModel"

答案 1 :(得分:0)

您的问题在于属性:IsDeadlineDateEnabledNameIndex。 当用户输入不同的名称时,您可以编辑名称并更改 Stask。 但是,您只为名称而不是 Stask 调用 OnPropertyChanged。 因此,您在 CommandParameter 中对 Stask 的绑定没有得到更新。 将 OnPropertyChanged(nameof(Stask)); 添加到这些属性中的每一个,它应该可以工作。