ListView“隐藏”子元素

问题描述

大家好,新年快乐! 我一直在寻找很多没有找到答案。所以我的问题是为什么 ListView、CarouselView、ScrollView 元素“隐藏”了它的子元素?为了澄清测试,我放置了一个简单的网格并添加了一些单选按钮 (x:name="radButton1") 和相应的标签 (x:name="label1")(冗余但单选按钮当前不显示其文本值)和图像。从后面的代码中,我可以使用 radButton1.GroupName、label1.Text 等访问它们,没有问题。但是,一旦我将它们移动到我的 ListView、CarouselView、ScrollView 并返回到后面的代码,我就会收到 radButton1、label1、image 等错误,它们不再在当前上下文中无法通过 Name 值检索? 我试图获取 listview 元素,然后查看 children 但这并没有向我显示这些元素,以便我可以像那里文本值或 IsVisible 等那样修改它们。在这一点上,我真的只关心 CarouselView是什么让我在用户交互中拥有更好的外观和感觉。

好的,这是我的 XAML 代码代码隐藏

<Image x:Name="greenCheck" Source="Greencheckmark.gif" IsVisible="{Binding GreenCheck}"></Image> 
<Image x:Name="GrayCheck" Source="Graycheckmark.gif" IsVisible="{Binding GrayCheck}"></Image> 
<Image x:Name="greenCheck1" Source="Greencheckmark.gif" IsVisible="{Binding GreenCheck1}"></Image> 
<Image x:Name="GrayCheck1" Source="Graycheckmark.gif" IsVisible="{Binding GrayCheck1}"></Image> 
Codebehind: 
GrayCheck = false; 
GreenCheck = true; 
GrayCheck1 = true; 
GreenCheck1 = false;

这正在设置,但在用户选择的任一选项上都没有显示绿色勾号?

TIA! 干杯! 瑞克...

解决方法

因为所有这些控件都是模板化的。您无法按名称访问模板化元素。

如果您的页面上只有一个 Label 并在 XAML 中为其分配一个 x:Name myLabel,则 XAML 编译器会创建一个名为 myLabel的变量> 您可以使用它从背后的代码中引用该控件。

但是,如果您的 ListView 在其模板中包含 Label,则可能会在运行时生成该 Label 的 0、12 或 1000 个副本,具体取决于ItemsSource 中的项目数。您不能通过名称来引用它,因为它不是单个实例,而是 0 到多个实例。

您应该使用数据绑定将 UI 的属性与 ViewModel 相关联,并在运行时更新您的 ViewModel 以更改您的 UI。这是 MVVM 模式的一部分。您不应在运行时直接修改模板化控件的 UI 属性。

,

但是,一旦我将它们移动到我的 ListView、CarouselView、ScrollView 并返回到后面的代码,我就会收到 radButton1、label1、image 等错误,它们不再在当前上下文中无法通过 Name 值检索?

正如 Jason 所说,你不能在 ListView 模板中通过 Name 访问控件,你可以通过 viewmodel 更改控件值。

 <StackLayout>
        <ListView
            x:Name="listview"
            HasUnevenRows="True"
            ItemsSource="{Binding radiomodels}">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>

                        <StackLayout>
                            <RadioButton
                                x:Name="radiobutton1"
                                GroupName="images"
                                Text="{Binding radiobutton1text}" />
                            <RadioButton
                                x:Name="radiobutton2"
                                GroupName="images"
                                Text="{Binding radiobutton2text}" />
                            <Switch x:Name="switch" IsToggled="{Binding ischeck,Mode=TwoWay}" />
                            <Image IsVisible="{Binding Path=IsToggled,Source={x:Reference switch}}" Source="{Binding image}" />
                            <Label Text="this is test" />
                            <Button
                                x:Name="btn1"
                                Clicked="btn1_Clicked"
                                Text="button" />
                        </StackLayout>

                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>

        <Button
            x:Name="btnupdate"
            Clicked="btnupdate_Clicked"
            Text="update listview item" />
    </StackLayout>

 public partial class Page1 : ContentPage
{
    public ObservableCollection<radiomodel> radiomodels { get; set; }
    public Page1()
    {
        InitializeComponent();
        radiomodels = new ObservableCollection<radiomodel>()
        {
            new radiomodel(){radiobutton1text="radio button1",radiobutton2text="radio button2",ischeck=false,image="a5.jpg"},new radiomodel(){radiobutton1text="radio button1",image="a6.jpg"},image="a7.jpg"},image="a8.jpg"},image="a9.jpg"}

        };
        this.BindingContext = this;
    }

   
    private void btnupdate_Clicked(object sender,EventArgs e)
    {
        radiomodel item = (radiomodel)listview.SelectedItem;
        var changeitem = radiomodels.FirstOrDefault(x => x.image == item.image);
        if(changeitem!=null)
        {
            changeitem.radiobutton1text = "test";
        }
    }
}

public class radiomodel:ViewModelBase
{
    private string _radiobutton1text;
    public string radiobutton1text
    {
        get { return _radiobutton1text; }
        set
        {
            _radiobutton1text = value;
            RaisePropertyChanged("radiobutton1text");
        }
    }

    private string _radiobutton2text;
    public string radiobutton2text
    {
        get { return _radiobutton2text; }
        set
        {
            _radiobutton2text = value;
            RaisePropertyChanged("radiobutton2text");
        }
    }
    private bool _ischeck;
    public bool ischeck
    {
        get { return _ischeck; }
        set
        {
            _ischeck = value;
            RaisePropertyChanged("ischeck");
        }
    }

    public string image { get; set; }
}

}

如果你还想在ListView中获取控件,可以按照下面的代码获取ListView选中的行控件。

 private void btn1_Clicked(object sender,EventArgs e)
    {

        Button button = sender as Button;
        StackLayout stacklayout =(StackLayout) button.Parent;
        RadioButton radiobutton1 = (RadioButton)stacklayout.Children[0];

        radiobutton1.Text = "test";

    }

ViewModelBase 是类,实现 INotifyPropertyChanged 接口,通知数据更新。

public class ViewModelBase : INotifyPropertyChanged
{
    
    public event PropertyChangedEventHandler PropertyChanged;

    
    public void RaisePropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            handler(this,new PropertyChangedEventArgs(propertyName));
        }
    }
}

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...