Сфокусироваться на следующей записи после максимальной длины 1 - PullRequest
0 голосов
/ 05 августа 2020

Я создал динамические c 20 записей и хочу сосредоточиться на следующей записи после того, как пользователь ввел di git, а максимальная длина записи равна 1. Фокус должен автоматически перемещаться на следующую запись. Я делюсь своим кодом . Заранее благодарим за помощь.

// модель

 public  class CrossingUIModel
    {
    public int Id { get; set; }
    public string FieldValue { get; set; }      
   }

// при изменении свойства

private ObservableCollection<CrossingUIModel> bindCrossingUIModel;

    public ObservableCollection<CrossingUIModel> BindCrossingUIModel
  {
    get { return bindCrossingUIModel; }
    set
    {
            bindCrossingUIModel = value;
        OnPropertyChanged(nameof(BindCrossingUIModel));
    }
  }

// создание ui

  public void CreateUI()
    {
        UserDialogs.Instance.ShowLoading();

        BindCrossingUIModel = new ObservableCollection<CrossingUIModel>();

        for (int i = 1; i < 21; i++)
        {
            CrossingUIModel model = new CrossingUIModel();
            model.Id = i;
            BindCrossingUIModel.Add(model);
        }

        UserDialogs.Instance.HideLoading();

    }

// xml файл

           <CollectionView x:Name="CrossingView" ItemsSource="{Binding BindCrossingUIModel, Mode=TwoWay}" SelectionMode="Multiple">
                        <CollectionView.ItemsLayout>
                        <GridItemsLayout Orientation="Vertical"  Span="10" />
                    </CollectionView.ItemsLayout>

                    <CollectionView.ItemTemplate>
                        <DataTemplate>
                            <StackLayout HorizontalOptions="FillAndExpand">
                                <Entry x:Name="Fields" Text="{Binding FieldValue, Mode=TwoWay}" 
                                       ReturnType="Next" MaxLength="1" Keyboard="Numeric" 
                                       TextChanged="Fields_TextChanged" ></Entry>
                            </StackLayout>
                        </DataTemplate>
                    </CollectionView.ItemTemplate>
                </CollectionView>

1 Ответ

0 голосов
/ 05 августа 2020

Поскольку вы использовали привязку данных, было бы лучше обрабатывать все logi c в ViewModel.

в коде за

Определить настраиваемую запись

public class MyEntry:Entry
{

     public static readonly BindableProperty IsFocusProperty =BindableProperty.Create("IsFocus", typeof(bool), typeof(MyEntry), false,propertyChanged: OnChanged);


    static void OnChanged(BindableObject bindable, object oldValue, object newValue)
    {
        var entry = bindable as MyEntry;

        var focus = (bool)newValue;

        if(focus)
        {
            entry.Focus();
        }
        else
        {
            entry.Unfocus();
        }

    }

    public bool IsFocus
    {
        get { return (bool)GetValue(IsFocusProperty); }
        set { 
            SetValue(IsFocusProperty, value);
            }
    }

    public MyEntry()
    {
        this.Focused += MyEntry_Focused;
        this.Unfocused += MyEntry_Unfocused;
    }

    private void MyEntry_Unfocused(object sender, FocusEventArgs e)
    {
        this.IsFocus = false;
    }

    private void MyEntry_Focused(object sender, FocusEventArgs e)
    {
        this.IsFocus = true;
    }
}

в модели

public  class CrossingUIModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    public int Id { get; set; }
   
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    string fieldValue;

    public string FieldValue
    {

        get
        {
            return fieldValue;
        }

        set
        {
            if (fieldValue != value)
            {
                fieldValue = value;
                OnPropertyChanged("FieldValue");
            }
        }
    }


    bool isFocus = false;

    public bool IsFocus
    {
        get
        {
            return isFocus;
        }

        set
        {
            if (isFocus != value)
            {
                isFocus = value;
                OnPropertyChanged("IsFocus");
            }
        }
    }

}

в ViewModel

public class MyViewModel
{
    public ObservableCollection<CrossingUIModel> BindCrossingUIModel { get; set; }

    public MyViewModel()
    {
        BindCrossingUIModel = new ObservableCollection<CrossingUIModel>();

        for (int i = 1; i < 21; i++)
        {
            CrossingUIModel model = new CrossingUIModel();
            model.Id = i;
            BindCrossingUIModel.Add(model);
        }

        foreach (CrossingUIModel model in BindCrossingUIModel)
        {
            model.PropertyChanged += Model_PropertyChanged;
        }


    }

    private void Model_PropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        if(e.PropertyName== "FieldValue")
        {
            var model = sender as CrossingUIModel;

            if(model.FieldValue.Length==1)
            {
                model.FieldValue = model.FieldValue.Substring(0, 1);

                model.IsFocus = false;

                int id = model.Id;

                BindCrossingUIModel[id].IsFocus = true;

            }

        }
    }
}

в xaml

Теперь нам не нужно устанавливать MaxLength и TextChanged больше.

<StackLayout HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
        <CollectionView x:Name="CrossingView" ItemsSource="{Binding BindCrossingUIModel, Mode=TwoWay}" SelectionMode="Multiple">
            <CollectionView.ItemsLayout>
                <GridItemsLayout  Orientation="Vertical"  Span="10" />
            </CollectionView.ItemsLayout>

            <CollectionView.ItemTemplate>
                <DataTemplate>
                    <StackLayout WidthRequest="100" HeightRequest="30" HorizontalOptions="FillAndExpand">
                        <local:MyEntry WidthRequest="80" BackgroundColor="LightBlue" HeightRequest="30" x:Name="Fields" Text="{Binding FieldValue, Mode=TwoWay}" 
                                       IsFocus="{Binding IsFocus, Mode=TwoWay}"
                                       ReturnType="Next"  Keyboard="Numeric" 
                                        ></local:MyEntry>
                    </StackLayout>
                </DataTemplate>
            </CollectionView.ItemTemplate>
        </CollectionView>
    </StackLayout>

Кстати, вы можете использовать Grid вместо StackLayout в качестве родительского макета записи.

введите описание изображения здесь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...