Binding command to a Button - yields no effect (Xamarin, MVVM):
notes:
- Pressing the Button and nothing happens: no CanExecute check occur.
- Binding a Button in a ContentPage which is Part of a Tabbed-Template
- functionality check and the rest of related MVVM binding works well: Defined a clicked-event and manually triggered the command from the code behind.
//Could someone see the reason?// editted editted, new: What would be a good practice when CanExecute relies on fields of a compound data type that are updated independently ? (*can take of the command parameter which is the compound data type, which is accessible to the command directly through the VM).
xaml for the View:
<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# code behind for the view (*including the Button-Clicked check for)
public partial class EditUnitPage : ContentPage
{
EditUnitViewModel editUVM;
public EditUnitPage()
{
InitializeComponent();
editUVM = new EditUnitViewModel();
BindingContext = editUVM;
}
public EditUnitPage(Unit6 unitSelected) : this()
{
if (unitSelected != null)
{
editUVM.EdittedUnit = unitSelected;
editUVM.ExistUnit = true;
}
}
protected override void OnAppearing()
{
base.OnAppearing();
}
//private void AddSave_Clicked(object sender, EventArgs e)
//{
// if (editUVM.AddSaveCMD.CanExecute(editUVM.EdittedUnit))
// {
// editUVM.AddSaveCMD.Execute(null);
// }
//}
}
C# MyCommand (newbie. using ICommand and not the Command Class)
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();
}
}
c# for VM (BaseViewModel implements INotify)
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());
}
}
}
xaml for the TabbedPage:
<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>