Xaml - 无法在类文件中获取项目名称(在listView中)

时间:2016-10-20 17:37:02

标签: 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 ; 

// Works - 它检测该标签的test1变量。

在我的listview中,当我尝试访问名为test2的标签时,它在我的cs文件中没有检测到它

test2.FontSize = 24 ; 

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

知道如何修复此问题或为我的cs文件中的列表项设置值吗?

3 个答案:

答案 0 :(得分:3)

将为ListView中的每个项实例化DataTemplate。这意味着ListView中的每个项都有一个test2实例。假设您在ListView中拥有1,000个项目。您考虑过哪个test2?框架无法猜测并且不会尝试。

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

如果您通过在代码隐藏中启用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>

答案 1 :(得分:0)

您无法按名称访问itemtemplate内的控件。

您有2个选项

  1. 在绑定项目中使用属性作为字体大小,并将其绑定到控件的fontsize。我认为这是更清洁的解决方案。

  2. 使用@ed

  3. 所述的触发器

    但我会明确地选择Mvvm

答案 2 :(得分:0)

如果您需要更多的程序化决策,这是另一种选择。 从ViewCell派生MyViewCell,除了MyViewCell之外,你的xml看起来都是一样的,我添加了绑定来显示东西。您需要添加本地代码引用以在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),则会设置字体。这是截图

enter image description here