1

私はextendedentryとカスタムレンダラークラスを持っています

public class ExtendedEntryRenderer : EntryRenderer
{
    protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
    {
        base.OnElementChanged(e);

        if (Control != null)
        {
            Control.Click += (sender, evt) =>
            {
                var nativeEditText = (global::Android.Widget.EditText)Control;
                nativeEditText.SetSelectAllOnFocus(true);

                new Handler().PostDelayed(delegate
                {
                     Control.InputType = 0;
                     try
                     {
                         InputMethodManager inputMethodManager = Control.Context.GetSystemService(Android.Content.Context.InputMethodService) as InputMethodManager;
                         if (inputMethodManager != null)
                         {
                             inputMethodManager.HideSoftInputFromWindow(Control.WindowToken, HideSoftInputFlags.None);
                         }
                     }
                     catch (Exception Ex)
                     {

                     }
                 }, 300L);
            };


            // Hide soft input keyboard
            Control.FocusChange += (sender, evt) =>
            {
                // Select all on entry focus
                var nativeEditText = (global::Android.Widget.EditText)Control;

                nativeEditText.SetSelectAllOnFocus(true);

                new Handler().PostDelayed(delegate
                 {
                     Control.InputType = 0;
                     try
                     {
                         InputMethodManager inputMethodManager = Control.Context.GetSystemService(Android.Content.Context.InputMethodService) as InputMethodManager;
                         if (inputMethodManager != null)
                         {
                            inputMethodManager.HideSoftInputFromWindow(Control.WindowToken, HideSoftInputFlags.None);
                         }
                     }
                     catch (Exception Ex)
                     {

                     }
                 }, 300L);
            };
        }
    }
}

私のカスタムエントリ:

public class ExtendedEntry : Entry
{

}

そして、私の XAML ファイルは次のようになります。

<local:ExtendedEntry x:Name="BarcodeEntry" Text="{Binding Barcode}" Margin="0,0,0,0" HorizontalOptions="FillAndExpand" VerticalOptions="Start">
    <Entry.Triggers>
        <Trigger TargetType="Entry" Property="IsFocused" Value="True">
            <Setter Property="BackgroundColor" Value="Yellow" />
            <Setter Property="TextColor" Value="Black" />
        </Trigger>
    </Entry.Triggers>       
</local:ExtendedEntry>

Trigger動作しません。

しかし、次のようにデフォルトのエントリ制御に変更すると:

<Entry x:Name="BarcodeEntry" Text="{Binding Barcode}" Margin="0,0,0,0"HorizontalOptions="FillAndExpand" VerticalOptions="Start">
    <Entry.Triggers>
        <Trigger TargetType="Entry" Property="IsFocused" Value="True">
            <Setter Property="BackgroundColor" Value="Yellow" />
            <Setter Property="TextColor" Value="Black" />
        </Trigger>
    </Entry.Triggers>       
</Entry>

Trigger作品。

私は何を間違えたのですか?

編集

ExportRendererXamarin.Formsの行はレンダラー クラスにあります。

[assembly: ExportRenderer(typeof(ExtendedEntry), typeof(ExtendedEntryRenderer))]
4

2 に答える 2

0

残念ながら、Xamarin の Entry / EntryRenderer システムには非常に問題があり、効果を追加することが非常に困難です。さらに悪いことに、動作するカスタム レンダラーを作成しましたが、基になるエントリ コントロールがレイアウトに追加されるとフリーズすることがありました。エントリに 2 つの異なるエフェクトを追加すると、まだフリーズしますが、フォーカス ファイアリングを取得して、1 つのエフェクトを正常に使用することができます。

元のフォーカス ハンドラが失われないようにするために、次のように取得しました。

private Android.Views.View.IOnFocusChangeListener focusListener = null;

private void ConfigureControl()
{
  EditText editText;

  editText = ((EditText)Control);
  this.focusListener = Control.OnFocusChangeListener;
  editText.FocusChange += EditText_FocusChange;

...

private void EditText_FocusChange(object sender, Android.Views.View.FocusChangeEventArgs e)
{
  EditText editText;

  editText = (EditText) sender;
  ...
  if (this.focusListener != null)
  {
    this.focusListener.OnFocusChange(editText,
      e.HasFocus);
  }

これにより、エフェクトが動作し、xamarin フォームにフォーカス イベントが発生します。残念ながら、これを 2 つの異なるエフェクトで実行してもうまくいきませんでした。おそらく、mono.android.view.View_OnFocusChangeListenerImplementor@a25f36e ハンドラが Android.Views.View.IOnFocusChangeListener にキャストしないか、キャストしますが、いくつかの内部バグが原因です。無限ループ。

エフェクトを使用して「x」を追加してAndroidエントリをクリアしていましたが、作成したエフェクトを使用してすべてのフォーカスを選択しようとしていました。どちらも Xamarin に含める候補として明らかです。なぜなら、基本的なオプションが頻繁に必要になりすぎて、それらをエフェクトやカスタム レンダラーに任せることが正当化されないからです。同じことを達成しようとしている場合は、私がしたことを行うことができます-「x」を追加する効果を追加し、非常に単純なすべてを選択する効果の代わりに、これでそれを達成できますが、 xamarin ビューに戻る機能コード:

  entry.Focused += (s, a) =>
  {
    Device.StartTimer(TimeSpan.FromMilliseconds(1),
      () =>
      {
        entry.CursorPosition = 0;
        entry.SelectionLength = (entry.Text ?? string.Empty).Length;
        return false;
      });
    ...
  };
  entry.Unfocused += (s, a) =>
  {
    ...
  };

カスタム レンダラーの開発やエフェクトの際限のない実験に費やす無駄な時間を誰かが節約できることを願っています。

于 2019-09-01T04:42:30.840 に答える