自定义控件可绑定属性中的值未更新-Xamarin表格/棱镜

时间:2018-10-23 08:50:01

标签: c# mvvm xamarin.forms custom-controls prism

我创建了一个自定义控件,该控件在StackControl中具有一个Entry和一个Label。然后,我通过名为 IsEntryEnabled 的可绑定属性公开了Entry的 IsEnabled 属性,该属性想绑定到我的VM的bool属性。但是它永远不会触发。知道我在做什么错吗?

自定义控件-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>

自定义控件-后台代码

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);
        }        
    }
}

查看模型

我正在尝试触发下面 EditForm()方法内的 IsEntryEnabled 属性。但这不起作用。

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()
        {

        }


    }

查看

我将 IsEditingEnabled 属性绑定到我的自定义控件中的 IsEntryEnabled 属性,该控件应该触发内部Entry中的 IsEnabled 属性。但是它永远不会触发。

 <controls:StandardFormEntry IsEntryEnabled="{Binding IsEditingEnabled}" EntryText="{Binding Text}" LabelText="Name" Grid.Column="0" Grid.Row="3"/>

1 个答案:

答案 0 :(得分:0)

在自定义控件中,需要为内容视图命名,并将该名称引用到绑定属性的来源,如下所示:

<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>