Focused或OnFocuseChange事件不会触发

时间:2016-08-03 20:29:28

标签: c# xaml xamarin xamarin.android xamarin.forms

我有自定义条目,我想知道它何时聚焦但它永远不会发生。我试图在自定义的android类中捕获它,并在xaml事件中聚焦但它没有做任何事情。 我之前也遇到过这个问题,但是没有解决它。 这是一堂课。评论栏中的事件。

using Android.Support.Design.Widget;
using Android.Text;
using Android.Views;
using Android.Views.InputMethods;
using GitRemote.CustomClasses;
using GitRemote.Droid.DependencyServices;
using GitRemote.Droid.Renderers;
using GitRemote.ViewModels;
using System.ComponentModel;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
using Color = Xamarin.Forms.Color;
using TextChangedEventArgs = Android.Text.TextChangedEventArgs;
using View = Android.Views.View;

[assembly: ExportRenderer(typeof(MaterialEntry), typeof(MaterialEntryRendererDroid))]

namespace GitRemote.Droid.Renderers
{
public class MaterialEntryRendererDroid : Xamarin.Forms.Platform.Android.AppCompat.ViewRenderer<Entry, View>
{
private TextInputLayout _nativeView;

    private TextInputLayout NativeView => _nativeView ?? ( _nativeView = InitializeNativeView() );

    protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
    {
        base.OnElementChanged(e);



        if ( e.OldElement != null ) return;

        // MaterialEntry Render Staff
        #region
        var ctrl = CreateNativeControl();
        SetNativeControl(ctrl);

        SetText();
        SetHintText();
        SetBackgroundColor();
        SetTextColor();
        SetIsPassword();
        #endregion

        if ( Control != null )
            switch ( e.NewElement.ClassId )
            {
                case "LoginEntry":
                    ViewSaver.SaveLoginView(Control);
                    //Element.Focused += (sender, args) =>
                    //{
                    //    ViewSaver.LastView = "LoginEntry";
                    //};
                    break;

                case "PasswordEntry":
                    SetSendButtonAction();
                    ViewSaver.SavePasswordView(Control);

                    //Element.Focused += (sender, args) =>
                    //{
                    //    ViewSaver.LastView = "PasswordEntry";
                    //};
                    break;

            }
    }

    protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        base.OnElementPropertyChanged(sender, e);

        if ( e.PropertyName == Entry.PlaceholderProperty.PropertyName )
        {
            SetHintText();
        }

        if ( e.PropertyName == Entry.TextColorProperty.PropertyName )
        {
            SetTextColor();
        }

        if ( e.PropertyName == VisualElement.BackgroundColorProperty.PropertyName )
        {
            SetBackgroundColor();
        }

        if ( e.PropertyName == Entry.IsPasswordProperty.PropertyName )
        {
            SetIsPassword();
        }

        if ( e.PropertyName == Entry.TextProperty.PropertyName )
        {
            SetText();
        }

    }

    private void EditTextOnTextChanged(object sender, TextChangedEventArgs textChangedEventArgs)
    {
        Element.Text = textChangedEventArgs.Text.ToString();
        NativeView.EditText.SetSelection(Element.Text.Length);
    }

    private void SetText()
    {
        NativeView.EditText.Text = Element.Text;
    }

    private void SetIsPassword()
    {
        NativeView.EditText.InputType = Element.IsPassword
            ? InputTypes.TextVariationPassword | InputTypes.ClassText
            : InputTypes.TextVariationVisiblePassword;
    }

    public void SetBackgroundColor()
    {
        NativeView.SetBackgroundColor(Element.BackgroundColor.ToAndroid());
    }

    private void SetHintText()
    {
        NativeView.Hint = Element.Placeholder;
    }

    private void SetTextColor()
    {
        if ( Element.TextColor == Color.Default )
            NativeView.EditText.SetTextColor(NativeView.EditText.TextColors);
        else
            NativeView.EditText.SetTextColor(Element.TextColor.ToAndroid());
    }

    private TextInputLayout InitializeNativeView()
    {
        var view = FindViewById<TextInputLayout>(Resource.Id.textInputLayout);
        view.EditText.TextChanged += EditTextOnTextChanged;
        return view;
    }

    protected override View CreateNativeControl()
    {
        return LayoutInflater.From(Context).Inflate(Resource.Layout.TextInputLayout, null);
    }

    /// <summary>
    /// If Action of our entry is Send than call method from Portable
    /// </summary>
    private void SetSendButtonAction()
    {
        NativeView.EditText.EditorAction += (sender, e) =>
        {
            if ( e.ActionId == ImeAction.Send )
            {
                ( ( LoginingPageViewModel )Element.BindingContext ).OnLogInTapped();
            }
            else
                e.Handled = false;
        };
    }


}
}

2 个答案:

答案 0 :(得分:0)

我用过:

 private void EditTextOnFocusChanged(object sender, FocusChangeEventArgs focusChangedEventArgs)
    {
        if ( focusChangedEventArgs.HasFocus )
            ViewSaver.SetLastView(Element.ClassId);
    }


view.EditText.FocusChange += EditTextOnFocusChanged;

它有效。

答案 1 :(得分:-2)

我知道你正在努力实现的目标,如果我是对的你正试图实现像Xamarin.Forms中的条目那样的谷歌材料设计。让我们来看看另一种方法;

步骤1:在PCL项目中创建一个类

public class CustomEntry : Entry
    {

    }

步骤2:在App.xaml中创建控件模板

<ControlTemplate x:Key="MyControlTemplate">
    <Grid>
      <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="Auto"/>
      </Grid.RowDefinitions>
      <controls:CustomEntry x:Name="myEntry" Text="{TemplateBinding Text, Mode=TwoWay}" HorizontalOptions="FillAndExpand" HorizontalTextAlignment="Start" IsPassword="{TemplateBinding IsPassword}" MinimumHeightRequest="25"/>
      <BoxView Grid.Row="1" BackgroundColor="#D2D2D2" HeightRequest="1" HorizontalOptions="FillAndExpand" VerticalOptions="Start">
        <BoxView.Triggers>
          <DataTrigger TargetType="BoxView" Binding="{Binding Source={x:Reference myEntry}, Path=IsFocused}" Value="true">
            <Setter Property="BackgroundColor" Value="Black" />
            <Setter Property="HeightRequest" Value="2"/>
          </DataTrigger>
        </BoxView.Triggers>
      </BoxView>
    </Grid>
  </ControlTemplate>  

步骤3:创建超级材料设计输入类

public class MyMaterialDesignEntry : ContentView, INotifyPropertyChanged
    {
        public static readonly BindableProperty TextProperty =
        BindableProperty.Create("Text", typeof(string), typeof(ContentPage), "");
        public static readonly BindableProperty IsPasswordProperty =
        BindableProperty.Create("IsPassword", typeof(bool), typeof(ContentPage), false);

        public string Text
        {
            get { return (string)GetValue(TextProperty); }
            set { SetValue(TextProperty, (string)value); }
        }       

        public bool IsPassword => (bool)GetValue(IsPasswordProperty);

        public MyMaterialDesignEntry()
        {
            ControlTemplate = (ControlTemplate)Application.Current.Resources.FirstOrDefault(x => x.Key == "MyControlTemplate").Value;
        }      
    }

步骤4:在xaml中使用超级材料设计条目

<StackLayout Orientation="Vertical" HorizontalOptions="FillAndExpand">
            <Label Text="Login"/>
            <controls:MyMaterialDesignEntry Text="{Binding Login, Mode=TwoWay}"/>
          </StackLayout>

不要忘记在页面xaml中添加适当的命名空间。无论如何它会告诉你。

祝大家好运:D