Настраиваемое представление контента с помощью Label-Entry дублирует формы Xamarin - PullRequest
0 голосов
/ 21 ноября 2018

У меня есть пользовательский вид контента с Label в качестве заголовка и другого Label в качестве детализации и редактирования Icon;при щелчке по значку метка сведений преобразуется в Entry для внесения изменений, и изменения переносятся в привязку.

Я связал несколько этих пользовательских представлений с различными свойствами одного и того же объекта и пытался редактировать каждый из них.один и переходите к следующему, проблема в том, что он, кажется, дублирует отдельные виды

Я также поставил x:Name, но все равно он дублирует то же значение для представлений над ним ..

Image1

Просто редактирование Фамилии

Edit of last name

Теперь, если я перееду3-й вид и редактировать его, он реплицирует новое значение на все ранее отредактированные значения.- для фамилии в этом случае, что странно, учитывая, что ее представление не совпадает с используемым на странице, и при отладке оно вызывает метод только один раз.

Issue image

Пользовательский просмотр содержимого :

<StackLayout Orientation="Horizontal"
                     VerticalOptions="Start"
                     Padding="25,10,25,10">
            <StackLayout x:Name="stackLayoutDetail"
                         HorizontalOptions="FillAndExpand">
                <Label x:Name="title"
                       Text="{Binding Title}" />
                <Label x:Name="detail"
                       Text="{Binding Detail}"
                       FontSize="Large"
                       FontAttributes="Bold" />
            </StackLayout>
            <Image x:Name="editIcon"
                   Source="edit_icon.png"
                   WidthRequest="25"
                   HeightRequest="25"
                   IsVisible="{Binding EditIconVisible}">
                <Image.GestureRecognizers>
                    <TapGestureRecognizer Tapped="EditIcon_Clicked" />
                </Image.GestureRecognizers>
            </Image>
        </StackLayout>

Код:

private static Entry newEntry = new Entry();

public static readonly BindableProperty DetailProperty = BindableProperty.Create(propertyName: nameof(Detail),
                                                                                            returnType: typeof(string),
                                                                                            declaringType: typeof(LabelledEntrywithIcon),
                                                                                            defaultValue: default(string));


        public string Detail
        {
            get
            {
                return (string)GetValue(DetailProperty);

            }
            set => SetValue(DetailProperty, value);
        }

private void EditIcon_Clicked(object sender, System.EventArgs e)
        {
            detailLabel = (Label)stackLayoutDetail.Children[1];
            stackLayoutDetail.Children.RemoveAt(1);
            newEntry.Text = Detail;
            stackLayoutDetail.Children.Add(newEntry);
            editIcon.IsVisible = false;
            newEntry.Completed += NewEntry_Completed;

        }


        private void NewEntry_Completed(object sender, System.EventArgs e)
        {
            try
            {
                var _newText = newEntry.Text;
                detailLabel.Text = _newText;
                stackLayoutDetail.Children.RemoveAt(1);
                stackLayoutDetail.Children.Add(detailLabel);
                Detail = _newText;
                editIcon.IsVisible = true;
            }
            catch (System.Exception ex)
            {

                Debug.WriteLine(ex.Message);
            }
        }

Страница

<local:LabelledEntrywithIcon x:Name="firstName"
                                     Title="First Name"
                                     Detail="{Binding Fella.FirstName}" />
        <local:LabelledEntrywithIcon  x:Name="lastname"
                                      Title="Last Name"
                                     Detail="{Binding Fella.LastName}" />
        <local:LabelledEntrywithIcon  x:Name="gender"
                                      Title="Gender"
                                     Detail="{Binding Fella.Gender}" />

Код:

ViewModel=new MainViewModel();
BindingContext = ViewModel;

Полный код для тестирования в Github-репо: https://github.com/pmahend1/CustomViewDuplicationIssue

Ответы [ 2 ]

0 голосов
/ 22 ноября 2018

Вместо создания новой записи, поиска и удаления метки и добавления новой записи после, вы могли бы упростить вашу проблему следующим образом:

<StackLayout Orientation="Horizontal"
                 VerticalOptions="Start"
                 Padding="25,10,25,10">
        <StackLayout x:Name="stackLayoutDetail"
                     HorizontalOptions="FillAndExpand">
            <Label x:Name="title"
                   Text="{Binding Title}" />
            <Label x:Name="detail"
                   Text="{Binding Detail}"
                   IsVisible="{Binding ShowLabel}"
                   FontSize="Large"
                   FontAttributes="Bold" />
             <Entry ... IsVisible="{Binding ShowEntry}" ... />
        </StackLayout>
        <Image x:Name="editIcon"
               Source="edit_icon.png"
               WidthRequest="25"
               HeightRequest="25"
               IsVisible="{Binding ShowLabel}">
            <Image.GestureRecognizers>
                <TapGestureRecognizer Tapped="EditIcon_Clicked" />
            </Image.GestureRecognizers>
        </Image>
    </StackLayout>

Обратите внимание, что я специально написал ... внутри элемента записикак заполнитель для всех настроек, которые вы, возможно, захотите сделать там (размер шрифта и т. д.).

Теперь вы добавляете два BindblyProperties (тип bool) ShowEntry и ShowLabel, где ShowLabel по умолчанию имеет значение true, а ShowEntry по умолчанию - false.Теперь все, что вам нужно сделать, это адаптировать ваше событие EditIcon_Clicked:

    private void EditIcon_Clicked(object sender, System.EventArgs e)
    {
        ShowLabel = false;
        ShowEntry = true;
        newEntry.Text = Detail;
        newEntry.Completed += NewEntry_Completed;

    }

и адаптировать NewEntry_Completed к

    private void NewEntry_Completed(object sender, System.EventArgs e)
    {
        try
        {
            var _newText = newEntry.Text;
            detailLabel.Text = _newText;
            ShowLabel = true;
            ShowEntry = false;
            Detail = _newText;
        }
        catch (System.Exception ex)
        {

            Debug.WriteLine(ex.Message);
        }
    }

По сути, это то же самое, что и ваше решение, однако вы избавляете себя от необходимоститолкать элементы пользовательского интерфейса в вашем коде, и особенно ошибки и ошибки, связанные с ним.

0 голосов
/ 21 ноября 2018

Странно, но я изменил строку кода, и теперь она работает, как и ожидалось.

В переменных класса изменилось private static Entry newEntry= new Entry(); на private static Entry newEntry;

в методе EditIcon_Clicked вместо newEntry.Text = Detail; используется

newEntry = new Entry { Text = Detail };

Я не уверен, почему он использовал ту же ссылку, хотя его новая запись для каждого LabelledEntrywithIcon

...