Xaml — Не удается получить имя элемента в файле класса (внутри ListView)

#c# #wpf #xaml #listview #xamarin

#c# #wpf #xaml #listview #xamarin

Вопрос:

Я создаю приложение XAML, и у меня возникают некоторые проблемы с привязкой моего файла xaml к его классу.

 <?xml version="1.0" encoding="utf-8" ?>
<ContentPage
x:Class="App.TestXaml"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml">

    <ContentPage.Content>

 <ListView x:Name="ListTest">

      <Label FontSize="12" x:Name="test1"/>


        <ListView.ItemTemplate>

                 <DataTemplate> 

                    <ViewCell>

                            <StackLayout Spacing="5" Orientation="Horizontal">

                                <Label FontSize="14" x:Name="test2"/>

                            </StackLayout>

                    </ViewCell>

                </DataTemplate>

          </ListView.ItemTemplate>

    </ListView>

    </ContentPage.Content>

</ContentPage>
  

в моем cs-файле testXaml.cs, который связан с этим xaml :

 test1.FontSize = 20 ; 
  

// Работает — он обнаруживает переменную test1 для этой метки.

Однако в моем listview, когда я пытаюсь получить доступ к ярлыку с именем test2, он не обнаруживает его в моем cs-файле

 test2.FontSize = 24 ; 
  

// Класс не обнаруживает test2 (имя test2 не существует в текущем контексте)

Есть идеи, как это исправить или настроить значение для элементов списка из моего файла cs?

Ответ №1:

Вы не можете получить доступ к элементам управления, которые находятся внутри itemtemplate, по их имени.

У вас есть 2 варианта

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

  2. Используйте триггеры, как описано @ed

Но я бы определенно выбрал Mvvm

Ответ №2:

Если вам нужно более программное решение, вот другой вариант. Извлеките MyViewCell из ViewCell, и ваш xml будет выглядеть так же, за исключением MyViewCell, и я добавил привязку, чтобы что-то показать. Вам нужно будет добавить ссылку на локальный код, чтобы использовать MyViewCell в xaml

  <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:ButtonRendererDemo;assembly=ButtonRendererDemo"
             x:Class="ButtonRendererDemo.ListCellAccessPage">  
  <ContentPage.Content>
    <ListView x:Name="ListTest" HasUnevenRows="true">
      <Label FontSize="12" x:Name="test1"/>
      <ListView.ItemTemplate>
        <DataTemplate>
          <local:MyViewCell>
            <StackLayout Spacing="5" Orientation="Horizontal">
              <Label FontSize="14" x:Name="test2" Text="{Binding Name}"/>
            </StackLayout>
          </local:MyViewCell>
        </DataTemplate>
      </ListView.ItemTemplate>
    </ListView>
  </ContentPage.Content>
</ContentPage>
  

Теперь вот код, лежащий в основе

 namespace ButtonRendererDemo
{
    public partial class ListCellAccessPage : ContentPage
    {
        MyListItem[] listItems = new MyListItem[]
        {
            new MyListItem { Name= "1" },
            new MyListItem{Name= "2" },
            new MyListItem{Name= "3" },
            new MyListItem{Name= "4" }
        };

        public ListCellAccessPage()
        {
            InitializeComponent();

            test1.Text = "List";
            ListTest.ItemsSource = listItems;
        }

    }

    class MyListItem
    {
        public string Name { get; set; }
    }

    class MyViewCell : ViewCell
    {

        protected override void OnChildAdded(Element child)
        {
            base.OnChildAdded(child);
            var label = child.FindByName<Label>("test2");
            if (label != null)
            {
                label.PropertyChanged -= Label_PropertyChanged1;//unsubscribe in case of cell reuse
                label.PropertyChanged  = Label_PropertyChanged1;
            }

        private void Label_PropertyChanged1(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            var label = sender as Label;
            if ((label != null) amp;amp; (e.PropertyName == "Text"))
            {
                if (label.Text == "3")
                    label.FontSize = 48;
                else
                    label.FontSize = 14;//in case of cell reuse
            }
        }       
    }
}
  

Итак, он проверяет содержимое вашей ячейки и, если оно подтверждает определенное условие (в данном случае имя равно 3), устанавливает шрифт. Вот скриншот

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