xamarin:Binding命令
将命令绑定到按钮-不产生任何效果(Xamarin、MVVM): 注:xamarin:Binding命令,xamarin,binding,command,Xamarin,Binding,Command,将命令绑定到按钮-不产生任何效果(Xamarin、MVVM): 注: 按下按钮,无任何反应:无CanExecute检查发生 绑定作为选项卡式模板一部分的ContentPage中的按钮 功能检查和其他相关的MVVM绑定工作良好:定义了一个单击事件,并从代码背后手动触发了命令 //有人知道原因吗?//编辑 编辑,新: 当CanExecute依赖于独立更新的复合数据类型字段时,什么是一个好的实践?(*可以使用命令参数,该参数是复合数据类型,命令可以通过VM直接访问该类型) 视图的xaml:
- 按下按钮,无任何反应:无CanExecute检查发生
- 绑定作为选项卡式模板一部分的ContentPage中的按钮
- 功能检查和其他相关的MVVM绑定工作良好:定义了一个单击事件,并从代码背后手动触发了命令
<ContentPage.Content>
<StackLayout>
<Entry Placeholder="Notes"/>
<Entry x:Name="courseIDEntry"
Text="{Binding CourseID, Mode=TwoWay}"
IsReadOnly="{Binding !ExistUnit}"
Placeholder="CourseID *"/>
<Entry x:Name="unitIDEntry"
Text="{Binding UnitID, Mode=TwoWay}"
IsReadOnly="{Binding !ExistUnit}"
Placeholder="UnitID *"/>enter code here
<Label Text="* Fields are mandatory"/>
<Button x:Name="AddSave"
Text="{Binding CommandText}"
Command="{Binding AddSaveCMD}"
CommandParameter="{Binding EdittedUnit}"/>
<!--Clicked="AddSave_Clicked"/>-->
</StackLayout>
</ContentPage.Content>enter code here
C#MyCommand(新手,使用ICommand而不是Command类)
c#用于VM(BaseViewModel实现INotify)
选项卡页的xaml:
<TabbedPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:views="clr-namespace:P205.Views"
x:Class="P205.Views.MyTabbedPage">
<views:UnitsPage Title="Units" />
<views:EditUnitPage x:Name="editOrAddUnit" Title="Edit U"/>
<views:DBChangesPage Title="Edit DB"/>
<views:CoursesPage Title="Course"/>
<ContentPage Padding="10">
</ContentPage>
当ViewModel定义类型为
ICommand
的属性时,ViewModel还必须包含或引用实现ICommand
接口的类。此类必须包含或引用Execute
和CanExecute
方法,并在CanExecute
方法可能返回不同值时触发CanExecuteChanged
事件
因此,您可以尝试以下更改:
public class AddSaveUnitCommand : ICommand
{
public EditUnitViewModel EditUVM { get; set; }
public event EventHandler CanExecuteChanged;
public AddSaveUnitCommand(EditUnitViewModel euvm)
{
EditUVM = euvm;
}
public bool CanExecute(object parameter)
{
var editted = parameter as Unit6;
if (editted != null )
{
if (!string.IsNullOrEmpty(editted.CourseID) || !string.IsNullOrEmpty(editted.UnitID))
return true;
}
return false;
}
public void Execute(object parameterf)
{
EditUVM.AddSaveUnitAsync();
CanExecuteChanged?.Invoke(this, EventArgs.Empty); //add this line.
}
}
非常感谢。1.问题是,代码甚至没有到达CanExcute:在CanExcute上使用断点,我只能在应用程序启动时在视图的InitializeComponent()上看到它。在运行期间和页面本身上-代码没有到达那里。2.正如我所提到的,我已经实现并绑定了其他命令:使用类似的功能注册和登录到应用程序,它们工作得很好。3.我发现的一个不同之处是,我在一个选项卡模板中处理contentPage。是否添加了
CanExecuteChanged?.Invoke(这个,EventArgs.Empty)代码>如上所述?当绑定第一次在按钮的命令
属性上定义时,当数据绑定以某种方式更改时,按钮在ICommand对象中调用CanExecute
方法。我还在tabbedpage中测试了它,它可以工作。您好,我已经尝试过了。它没有到达那条线。我一直在寻找,并了解到没有直接绑定到OnPropertyChanged通知属性。1.我将从这里继续:学习在只更新复合数据类型上的字段时引发OnPropertyChanged()的良好实践。2.它与最初怀疑的选项卡式模板无关,因此我将编辑该主题。谢谢。如果可能的话,你可以分享你的项目,我会测试一下。
public class EditUnitViewModel : BaseViewModel
{
public AddSaveUnitCommand AddSaveCMD { get; set; }
private Unit6 edittedUnit;
public Unit6 EdittedUnit
{
get { return edittedUnit; }
set { edittedUnit = value; OnPropertyChanged(); }
}
private bool existUnit;
public bool ExistUnit
{
get { return existUnit; }
set
{
existUnit = value;
//OnPropertyChanged();
}
}
public string CommandText
{
get { return ExistUnit? "Save": "Add"; }
}
public string CourseID
{
get { return EdittedUnit.CourseID; }
set { EdittedUnit.CourseID = value; OnPropertyChanged(); }
}
public string UnitID
{
get { return EdittedUnit.UnitID; }
set { EdittedUnit.UnitID = value; OnPropertyChanged(); }
}
public EditUnitViewModel()
{
EdittedUnit = new Unit6();
AddSaveCMD = new AddSaveUnitCommand(this);
}
public async void AddSaveUnitAsync()
{
var curPage = App.Current.MainPage;
try
{
switch (ExistUnit)
{
case false: //insert new unit to the DB
EdittedUnit.UnitKey = ""; //Todo: look for more elegant of assigning auto value to property
Unit6.Insert(EdittedUnit);
break;
case true: //update details on existing unit
EdittedUnit.UnitKey = ""; //Todo: look for more elegant of assigning auto value to property
Unit6.Update(EdittedUnit);
break;
}
await curPage.DisplayAlert("Success", "Unit was succesffuly updateded", "OK");
}
catch
{
await curPage.DisplayAlert("Error", "Unit was not updated", "OK");
}
finally
{
EdittedUnit = null;
await curPage.Navigation.PushAsync(new MyTabbedPage());
}
}
}
<TabbedPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:views="clr-namespace:P205.Views"
x:Class="P205.Views.MyTabbedPage">
<views:UnitsPage Title="Units" />
<views:EditUnitPage x:Name="editOrAddUnit" Title="Edit U"/>
<views:DBChangesPage Title="Edit DB"/>
<views:CoursesPage Title="Course"/>
<ContentPage Padding="10">
</ContentPage>
public class AddSaveUnitCommand : ICommand
{
public EditUnitViewModel EditUVM { get; set; }
public event EventHandler CanExecuteChanged;
public AddSaveUnitCommand(EditUnitViewModel euvm)
{
EditUVM = euvm;
}
public bool CanExecute(object parameter)
{
var editted = parameter as Unit6;
if (editted != null )
{
if (!string.IsNullOrEmpty(editted.CourseID) || !string.IsNullOrEmpty(editted.UnitID))
return true;
}
return false;
}
public void Execute(object parameterf)
{
EditUVM.AddSaveUnitAsync();
CanExecuteChanged?.Invoke(this, EventArgs.Empty); //add this line.
}
}