2016-11-01 8 views
0

ジャンプする原因:我々のアプリでMvvmCross Androidのコンバータは、カーソルが、私たちは、AndroidでのEditTextコントロールに関連してMvvmCrossでのコンバータに問題がある

、ユーザは、ユーザデータを挿入します。このデータをコンバーター内で計算してから、ビューモデルにデータを書き込む必要があります。

ユーザーがエントリを元に戻さない限り、これは機能します。 つまり、バックキーを使用すると、 "。"の前の最後の10進数に達するまで値が正しく編集されます。 (たとえば、55.99、55.9に達したとき)。 ".9"は正しく削除されますが、curosorは残りの "55"を上回ります。 この厄介な行動をどうやって解決できますか?

ビューモデルエキス:

private Nullable mdValue1 = null; 

public Nullable<decimal> Value1 
{ 
    get { return mdValue1; } 
    set 
    { 
    SetProperty(ref mdValue1, value); 
    } 
} 

private Nullable<decimal> mdValue2; 

public Nullable<decimal> Value2 
{ 
    get { return mdValue2; } 
    set 
    { 

     SetProperty(ref mdValue2, value, nameof(Value2)); 

    } 
} 

コンバータ(簡体字):

public class DecimalToStringValueConverter : MvxValueConverter<Nullable<decimal>, string> 
{ 
protected override string Convert(Nullable<decimal> poValue, Type poTargetType, object poParameter, CultureInfo poCulture) 
{ 
    if (!poValue.HasValue) 
    { 
     return null; 
    } 

    return poValue.Value.ToString(); 
} 

protected override Nullable<decimal> ConvertBack(string value, Type targetType, object parameter, CultureInfo culture) 
{ 
    if (string.IsNullOrWhiteSpace(value)) 
    { 
     return null; 
    } 

    return decimal.Parse(value); 
} 
} 

構成

アンドロイドバージョン:4.4/5.1/7

プラットフォーム:点を除去し、10進数に変換されたときに起こっていると思わXamarin

答えて

1

は、ビューモデルの値で得られた変化は、ビューモデルは、の値を設定させるのEditTextに、異なるされますEditText。

例:ユーザーは、59.9に入る9バックスペース。これにより、EditTextの値は59.となり、ViewModelへの小数として59に解析されます。 59.59と等しくないため、ViewModelはEditTextの値を59に更新します。これは、カーソルが開始位置にジャンプする原因となります。

これを解決する簡単な方法の1つは、最後の小数点以下を削除するときにカーソルが常にEditTextの最後に配置されるようにするカスタムバインドを作成することです。これは、SetValueImplメソッドでカーソルを位置付けるSetSelectionを使用して実行できます。

public class DecimalEditTextTargetBinding : MvxConvertingTargetBinding 
{ 
    protected EditText EditTextControl => Target as EditText; 

    private IDisposable _subscription; 

    public DecimalEditTextTargetBinding(EditText target) : base(target) 
    { 
     if (target == null) 
      MvxBindingTrace.Error($"Error - EditText is null in {nameof(DecimalEditTextTargetBinding)}"); 
    } 

    public override Type TargetType => typeof(string); 
    public override MvxBindingMode DefaultMode => MvxBindingMode.TwoWay; 

    protected override void SetValueImpl(object target, object value) 
    { 
     ((TextView)target).Text = (string)value; 
     EditTextControl.SetSelection(EditTextControl.Text?.Length ?? 0); 
    } 

    public override void SubscribeToEvents() 
    { 
     if (EditTextControl == null) 
      return; 

     _subscription = EditTextControl.WeakSubscribe<TextView, AfterTextChangedEventArgs>(
      nameof(EditTextControl.AfterTextChanged), 
      EditTextOnAfterTextChanged); 
    } 

    private void EditTextOnAfterTextChanged(object sender, AfterTextChangedEventArgs e) 
    { 
     FireValueChanged(EditTextControl.Text); 
    } 

    protected override void Dispose(bool isDisposing) 
    { 
     if (isDisposing) 
     { 
      _subscription?.Dispose(); 
      _subscription = null; 
     } 
     base.Dispose(isDisposing); 
    } 
} 

そしてあなたSetup.csにカスタムバインディングを登録します。

protected override void FillTargetFactories(IMvxTargetBindingFactoryRegistry registry) 
{ 
    base.FillTargetFactories(registry); 
    registry.RegisterCustomBindingFactory<EditText>("DecimalText", inputField => new DecimalEditTextTargetBinding(inputField)); 
} 

XMLの使用:事前MvvmCross 4.4.0用のバインディングの

<EditText 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:inputType="numberDecimal|numberSigned" 
    local:MvxBind="DecimalText DecimalToString(Value1)" /> 

例:

public class DecimalEditTextTargetBinding : MvxConvertingTargetBinding 
{ 
    private bool _subscribed; 

    public DecimalEditTextTargetBinding(EditText target) : base(target) 
    { 
     if (target == null) 
      MvxBindingTrace.Error($"Error - EditText is null in {nameof(DecimalEditTextTargetBinding)}"); 
    } 

    protected EditText EditTextControl => Target as EditText; 

    public override Type TargetType => typeof(string); 

    public override MvxBindingMode DefaultMode => MvxBindingMode.TwoWay; 

    protected override void SetValueImpl(object target, object value) 
    { 
     ((TextView)target).Text = (string)value; 
     EditTextControl.SetSelection(EditTextControl.Text?.Length ?? 0); 
    } 

    public override void SubscribeToEvents() 
    { 
     if (EditTextControl == null) 
      return; 

     EditTextControl.AfterTextChanged += EditTextOnAfterTextChanged; 
     _subscribed = true; 
    } 

    private void EditTextOnAfterTextChanged(object sender, AfterTextChangedEventArgs e) 
    { 
     FireValueChanged(EditTextControl.Text); 
    } 

    protected override void Dispose(bool isDisposing) 
    { 
     if (isDisposing && EditTextControl != null && _subscribed) 
     { 
      EditTextControl.AfterTextChanged -= EditTextOnAfterTextChanged; 
      _subscribed = false; 
     } 

     base.Dispose(isDisposing); 
    } 
} 
+0

こんにちは!まずはお時間をいただきありがとうございます!あなたは私たちを大いに助けてくれました。私たちはXamarinにとって全く新しいです。 curserは今働きます。他の問題は "WeakSubscribe"で盛り上がった。見つけられず、赤色にマークされています。使用するアセンブリはありますか? – Mephistopheles

+0

'WeakSubscribe'は、[Mvvmcross 4.4.0。](https://github.com/MvvmCross/MvvmCross/commit/b2e67d8994859cd68d42fb87a287eb462a44ba49)に追加された' MvvmCross.Platform.WeakSubscription'の下で利用できます。あなたが古いあなたは代わりに 'AfterTextChanged'に直接購読することができます。答えを更新して例を含める。 – Plac3Hold3r

+0

今、4.4に入っています。本当にありがとう、本当にありがとう! – Mephistopheles

関連する問題