Reputation: 985
I created a custom control which has an Entry and a Label inside a StackControl. Then I exposed the IsEnabled property of the Entry thorough a bindable property called IsEntryEnabled which I wanted to bind to a bool property of my VM. But it never triggers. Any idea what am I doing wrong here?
Custom control - Xaml
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:effects="clr-namespace:VMSTablet.Effects;assembly=VMSTablet"
x:Class="VMSTablet.Controls.StandardFormEntry">
<StackLayout >
<Label Text="{Binding LabelText}" Style="{StaticResource DefaultLabelStyle}" TextColor="{StaticResource DarkGreenColor}"/>
<Entry x:Name="CustomEntry" Text="{Binding Text}"
IsEnabled="{Binding IsEntryEnabled}"
Keyboard="{Binding Keyboard}"
Behaviors="{Binding Behaviors}"
TextColor="{StaticResource DarkGreenColor}"
Placeholder="{Binding Placeholder}" Style="{StaticResource DefaultEntryStyle}" >
<Entry.Effects>
<effects:EntryBarColorEffect/>
</Entry.Effects>
</Entry>
</StackLayout>
</ContentView>
Custom control - Code Behind
namespace VMST.Controls
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class StandardFormEntry
{
public event EventHandler OnTextChanged;
public event EventHandler OnUnfocused;
public event EventHandler OnFocused;
public static readonly BindableProperty PlaceholderProperty =
BindableProperty.Create("Placeholder", typeof(string), typeof(StandardFormEntry), string.Empty);
public static readonly BindableProperty LabelTextProperty =
BindableProperty.Create("LabelText", typeof(string), typeof(StandardFormEntry), string.Empty);
public static readonly BindableProperty EntryTextProperty =
BindableProperty.Create("EntryText", typeof(string), typeof(StandardFormEntry), string.Empty);
public static BindableProperty IsEntryEnabledProperty =
BindableProperty.Create("IsEntryEnabled", typeof(bool), typeof(StandardFormEntry), true);
public static readonly BindableProperty KeyboardProperty =
BindableProperty.Create("Keyboard", typeof(Keyboard), typeof(StandardFormEntry), Xamarin.Forms.Keyboard.Default);
public static readonly BindableProperty BehaviorsProperty =
BindableProperty.Create(nameof(Behaviors), typeof(IList<Behavior>), typeof(StandardFormEntry));
public string LabelText
{
set
{
SetValue(LabelTextProperty, value);
}
get => (string)GetValue(LabelTextProperty);
}
public string EntryText
{
set => SetValue(EntryTextProperty, value);
get => (string)GetValue(EntryTextProperty);
}
public string Placeholder
{
set => SetValue(PlaceholderProperty, value);
get => (string)GetValue(PlaceholderProperty);
}
public bool IsEntryEnabled
{
set
{
SetValue(IsEntryEnabledProperty, value);
}
get => (bool)GetValue(IsEntryEnabledProperty);
}
public Keyboard Keyboard
{
set => SetValue(KeyboardProperty, value);
get => (Keyboard)GetValue(KeyboardProperty);
}
public IList<Behavior> Behaviors
{
set => SetValue(BehaviorsProperty, value);
get => (IList<Behavior>)GetValue(BehaviorsProperty);
}
public StandardFormEntry()
{
InitializeComponent();
BindingContext = this;
CustomEntry.BindingContext = this;
PropertyChanged += StandardFormEntry_PropertyChanged;
CustomEntry.Unfocused += CustomEntry_Unfocused;
CustomEntry.TextChanged += CustomEntry_TextChanged;
CustomEntry.Focused += CustomEntry_Focused;
}
private void StandardFormEntry_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == IsEntryEnabledProperty.PropertyName)
{
**//This never happens!**
}
}
protected override void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
base.OnPropertyChanged(propertyName);
}
private void CustomEntry_Focused(object sender, FocusEventArgs e)
{
OnFocused?.Invoke(sender, e);
}
private void CustomEntry_TextChanged(object sender, TextChangedEventArgs e)
{
OnTextChanged?.Invoke(sender, e);
}
private void CustomEntry_Unfocused(object sender, FocusEventArgs e)
{
OnUnfocused?.Invoke(sender, e);
}
}
}
View Model
I'm trying to trigger the IsEntryEnabled property inside the EditForm() method below. But it doesn't work.
public class PassRegistrationPageViewModel : ViewModelBase
{
public DelegateCommand AddressCommand { get; set; }
public DelegateCommand EditCommand { get; set; }
public DelegateCommand ConfirmCommand { get; set; }
public PassRegistrationPageViewModel(INavigationService navigationService) : base(navigationService)
{
Title = "Page Title";
AddressCommand = new DelegateCommand(ShowBuildings);
EditCommand = new DelegateCommand(EditForm);
ConfirmCommand = new DelegateCommand(ConfirmPass);
//IsQrVisible = false;
}
private bool _isQrVisible;
public bool IsQrVisible
{
get { return _isQrVisible; }
set {
SetProperty(ref _isQrVisible, value);
}
}
private bool _isEditingEnabled;
public bool IsEditingEnabled //Bound to the view below
{
get { return _isEditingEnabled; }
set { SetProperty(ref _isEditingEnabled, value); }
}
private string _text;
public string Text
{
get { return _text; }
set
{
SetProperty(ref _text, value);
}
}
private async void ShowBuildings()
{
await NavigationService.NavigateAsync(nameof(BuildingListPage));
}
public void EditForm()
{
IsEditingEnabled = IsEditingEnabled ? false : true;
}
public void ConfirmPass()
{
}
}
View
I bind the IsEditingEnabled property to IsEntryEnabled property in my custom control which is supposed to trigger the IsEnabled property in the Entry inside. But it never triggers.
<controls:StandardFormEntry IsEntryEnabled="{Binding IsEditingEnabled}" EntryText="{Binding Text}" LabelText="Name" Grid.Column="0" Grid.Row="3"/>
Upvotes: 2
Views: 2154
Reputation: 689
In your custom control, you need to give a name to your content view and refer the name to the source of the binding property, like below:
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:effects="clr-namespace:VMSTablet.Effects;assembly=VMSTablet"
x:Class="VMSTablet.Controls.StandardFormEntry"
x:Name="CustomEntryControl">
<StackLayout >
<Label Text="{Binding LabelText}" Style="{StaticResource DefaultLabelStyle}" TextColor="{StaticResource DarkGreenColor}"/>
<Entry x:Name="CustomEntry" Text="{Binding Text}"
IsEnabled="{Binding IsEntryEnabled, Source={x:Reference CustomEntryControl}}"
Keyboard="{Binding Keyboard}"
Behaviors="{Binding Behaviors}"
TextColor="{StaticResource DarkGreenColor}"
Placeholder="{Binding Placeholder}" Style="{StaticResource DefaultEntryStyle}" >
<Entry.Effects>
<effects:EntryBarColorEffect/>
</Entry.Effects>
</Entry>
</StackLayout>
Upvotes: 1