【问题标题】:Xaml - Unable to get item Name in class file (inside listView)Xaml - 无法在类文件中获取项目名称(在 listView 内)
【发布时间】:2016-10-20 17:37:02
【问题描述】:

我正在制作一个 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 变量。

然而,在我的列表视图中,当我尝试访问名为 test2 的标签时,它没有在我的 cs 文件中检测到它

test2.FontSize = 24 ; 

// 类未检测到test2(当前上下文中不存在名称test2)

知道如何解决这个问题或为我的cs文件中的列表项设置一个值吗?

【问题讨论】:

    标签: c# wpf xaml listview xamarin


    【解决方案1】:

    将为ListView 中的每个 项实例化DataTemplate。这意味着 ListView 中的 每个 项都有一个 test2 实例。假设您在 ListView 中有 1,000 个项目。你想到了哪个test2?框架猜不出来,也不会尝试。

    你想要的是DataTemplate.Triggers。确切的细节将取决于你用来决定字体大小的确切逻辑,你没有分享。这是使用触发器的DataTemplate示例,您可以按原样粘贴并查看它的工作原理。如果你给自己的DataTemplate 一个或多个触发器,那看起来很像这样。在您的列表视图项模板中,DataTrigger.Binding 将绑定到列表视图项的属性,无论它们是什么。

    如果您通过在代码隐藏中启动 ListViewItem 来填充您的列表视图,那么您正在借用很多您并不真正需要的麻烦。

    <ContentControl Content="Test">
        <ContentControl.ContentTemplate>
            <DataTemplate>
                <Label 
                    x:Name="myLabel"
                    Content="{Binding}" 
                    />
                <DataTemplate.Triggers>
                    <DataTrigger Binding="{Binding Length}" Value="4">
                        <Setter TargetName="myLabel" Property="Background" Value="LawnGreen" />
                        <Setter TargetName="myLabel" Property="FontSize" Value="40" />
                    </DataTrigger>
                    <DataTrigger Binding="{Binding Length}" Value="5">
                        <Setter TargetName="myLabel" Property="Background" Value="OrangeRed" />
                        <Setter TargetName="myLabel" Property="FontSize" Value="9" />
                    </DataTrigger>
                </DataTemplate.Triggers>
            </DataTemplate>
        </ContentControl.ContentTemplate>
    </ContentControl>
    

    【讨论】:

      【解决方案2】:

      您无法通过名称访问 itemtemplate 中的控件。

      你有两个选择

      1. 使用绑定项中的字体大小属性并将其绑定到控件的字体大小。我认为这是更干净的解决方案。

      2. 使用@ed 描述的触发器

      但我肯定会选择 Mvvm

      【讨论】:

        【解决方案3】:

        如果您需要更多程序化决策,这里是另一种选择。 从 ViewCell 派生 MyViewCell 并且您的 xml 看起来与 MyViewCell 相同,并且我添加了绑定以显示某些内容。您需要添加本地代码引用才能在 xaml 中使用 MyViewCell

         <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) && (e.PropertyName == "Text"))
                    {
                        if (label.Text == "3")
                            label.FontSize = 48;
                        else
                            label.FontSize = 14;//in case of cell reuse
                    }
                }       
            }
        }
        

        因此,它会检查单元格的内容,如果确认某些条件(在本例中名称为 3),它会设置字体。这是截图

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-04-05
          • 1970-01-01
          相关资源
          最近更新 更多