tendai
tendai

Reputation: 1251

Failing to bind to Bindable Property [Prism Application Xamarin Forms]

I have a custom control and would like to manipulate it by changing a bound value from a ViewModel.

I have structured my code as shown below. The problem is, whenever i change the value in the ViewModel, there is no change triggered in the Custom control BindableProperty.

What am i getting wrong here.

Custom Control (StepWizardControl.cs):

public class StepWizardControl : StackLayout
{
    public static readonly BindableProperty ActiveStepNumberProperty = BindableProperty.Create(nameof(ActiveStep), typeof(int), typeof(StepWizardControl), 1, defaultBindingMode: BindingMode.TwoWay);

    public int ActiveStep
    {
        get => (int)GetValue(ActiveStepNumberProperty);
        set => SetValue(ActiveStepNumberProperty, value);
    } 

   public StepWizardControl()
   {
      PropertyChanged += StepWizardControl_PropertyChanged;
   }

   private void StepWizardControl_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
   {
        if (e.PropertyName.Equals(nameof(ActiveStep)))
        {
            switch (ActiveStep)
            {
                case 1:
                    DoStep1();
                    break;
                case 2:
                    DoStep2();
                    break;
                default:
                    DoSomethingElse();
            }
        }  
    }
}    

StepWizardPage.xaml (page in which control is used):

<?xml version="1.0" encoding="UTF-8" ?>
<ContentPage
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:prism="http://prismlibrary.com"
    prism:ViewModelLocator.AutowireViewModel="True"
    xmlns:controls="StepWizardControlNameSpace"
    x:Class="MyClass">
    <ContentPage.Content>
           <StackLayout>

            <controls:StepWizardControl ActiveStep="{Binding CurrentStep, Mode=TwoWay}"/>
            <Button Text="Go Forward" Command="{Binding ToggleStepsCommand}"/>

           </StackLayout>

    </ContentPage.Content>
</ContentPage>

StepWizardPageViewModel:

 public class StepWizardPageViewModel : PrismBaseViewModel, INavigatedAware
    {

        public int CurrentStep { get; set; }

        public DelegateCommand ToggleStepsCommand { get; }
       
        public StepWizardPageViewModel(INavigationService navigationService) : base(navigationService)
        {
            ToggleStepsCommand = new DelegateCommand(async () => { await OnToggleStepsCommand(); });
        }

        private async Task OnToggleStepsCommand()
        {
            CurrentStep++; //change the control UI to show current step
        }
    }

Upvotes: 1

Views: 215

Answers (1)

ColeX
ColeX

Reputation: 14475

  1. The name of the BindableProperty defined in custom control should be corresponding to the property , in you code change ActiveStepNumberProperty to ActiveStepProperty
  public static readonly BindableProperty ActiveStepProperty = 
            BindableProperty.Create(
                nameof(ActiveStep), 
                typeof(int), 
                typeof(StepWizardControl),
                1,
                BindingMode.TwoWay
                );
        public int ActiveStep
        {
            get => (int)GetValue(ActiveStepProperty);
            set => SetValue(ActiveStepProperty, value);
        }
  1. It should notify the change in viewmodel , then the BindableProperty would be changed after then.
 public class StepWizardPageViewModel :BaseViewModel 
    {
        private int currentStep;
        public int CurrentStep {
            get {
                return currentStep;
            } 
            set {
                currentStep = value;
                NotifyPropertyChanged();  //add the notify method defined in PrismBaseViewModel 
            }
        }

    //xxx
}

Upvotes: 2

Related Questions