问题描述
我正在尝试制作一个应用程序,将主题和任务保存在本地数据库中。添加新任务时我卡住了。我为 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,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,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,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,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);
}
}
}
我感谢任何形式的帮助!
解决方法
我找到了解决办法。我把它放在我的 XAML 代码中:
xmlns:viewmodel="clr-namespace:MyApp.ViewModel"
x:DataType="viewmodel:NewTaskViewModel"
,
您的问题在于属性:IsDeadline
、DateEnabled
、Name
和 Index
。
当用户输入不同的名称时,您可以编辑名称并更改 Stask。
但是,您只为名称而不是 Stask 调用 OnPropertyChanged。
因此,您在 CommandParameter 中对 Stask 的绑定没有得到更新。
将 OnPropertyChanged(nameof(Stask));
添加到这些属性中的每一个,它应该可以工作。