如何解决如何通过Xamarin外部的按钮单击在列表视图中找到控件
我有一个图像按钮。当单击图像按钮时,我要显示或隐藏存在于列表视图中的复选框。我尝试过的内容如下。
按钮
<ImageButton Source="plus.png" x:Name="imgBtnPlus" Grid.Column="1" Margin="0,10,0" Clicked="imgBtnPlus_Clicked" />
列表视图
<ListView ItemsSource="{Binding NewOrders}" x:Name="lstNewOrders" ItemTapped="lstNewOrders_ItemTapped" RowHeight="80" >
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid BackgroundColor="#fefefe" Padding="10">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="60"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="30"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="auto"></RowDefinition>
</Grid.RowDefinitions>
<Image Source="bluecircle.png" Grid.Column="0" Grid.Row="0" VerticalOptions="Start"></Image>
<Grid Grid.Column="1" Grid.Row="0" Margin="0,5" VerticalOptions="Center">
<Grid.RowDefinitions>
<RowDefinition Height="20"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Label Text="{Binding number}" FontAttributes="Bold" Grid.Column="0" Grid.Row="0" FontSize="18" x:Name="lblNumber" />
<Label Text="{Binding Description}" Grid.Column="0" Grid.Row="1" FontSize="12" />
</Grid>
<CheckBox IsChecked="False" Grid.Column="2" VerticalOptions="Center" Grid.Row="0" x:Name="chklstNew" Style="{StaticResource ckhMultipleOrders}" />
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
背后的代码
当我尝试访问这样的复选框时,我总是得到null。有人可以帮忙吗?
private void imgBtnPlus_Clicked(object sender,System.EventArgs e)
{
CheckBox chk = lstNewOrders.FindByName("chklstNew") as CheckBox;
}
解决方法
我从没使用过FindByName
,因此我无法确定它是否可以在ListView
上工作以获取其子级,但是如果这样做,将会有多个CheckBox
ListView
中的实例,基本上,ListView
接收DataTemplate
内部的内容并重复。因此,如果 有效,它宁愿是IEnumerable
实例的数组或CheckBox
,因此as CheckBox
当然就是null
。>
话虽如此,我认为您正在使事情变得过于复杂。由于您正在使用绑定,因此我假设您已经使用了 MVVM 种类,为什么不使用它来显示/隐藏复选框?
只需添加带有更改通知(bool ShowCheckBoxes
的属性INotifyPropertyChanged
(或其他名称,只要赋予它有意义的名称)即可,但是如果您已经在使用MVVM,则应该很熟悉)和命令{ {1}}(再次是有意义的名称!)。在命令调用的方法中,只需设置public Command OnFooBarButtonClickedCommand { get; set; }
属性
ShowCheckBoxes
最后,您可以更新XAML以使用该属性。无论如何,您不能简单地为此使用private void OnFooBarButtonClicked()
{
ShowCheckBoxes = true; // or whatever
}
,因为复选框的绑定上下文是列表中的项目。无论如何,您可以使用一个{Binding ShowCheckBoxes}
属性。只需为您的Page或最上面的视图命名,例如Source
如果是页面,现在您可以在x:Name="Page"
Binding
,
欢迎您!
在共享代码中,您没有充分利用Xamarin Forms中的 MVVM 。定义模型的IsShow
属性有两种方法。
一种方法是为ViewModel(为ContentPage绑定)声明一个IsShow
属性。
例如,ViewModel如下:
public class CheckModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public List<CheckItem> NewOrders { get; set; }
private bool checkShow;
public bool CheckShow
{
set
{
if (checkShow != value)
{
checkShow = value;
OnPropertyChanged("CheckShow");
}
}
get
{
return checkShow;
}
}
public CheckModel()
{
CheckShow = false;
NewOrders = new List<CheckItem>();
NewOrders.Add(new CheckItem() { Number = "1",Description = "1 description"});
NewOrders.Add(new CheckItem() { Number = "2",Description = "2 description"});
NewOrders.Add(new CheckItem() { Number = "3",Description = "3 description"});
NewOrders.Add(new CheckItem() { Number = "4",Description = "4 description"});
NewOrders.Add(new CheckItem() { Number = "5",Description = "5 description"});
}
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this,new PropertyChangedEventArgs(propertyName));
}
}
并在ContentPage中按如下方式使用:
public partial class PageListViewCheckBox : ContentPage
{
CheckModel checkModel;
public PageListViewCheckBox()
{
InitializeComponent();
checkModel = new CheckModel();
BindingContext = checkModel;
}
private void Button_Clicked(object sender,EventArgs e)
{
if (checkModel.CheckShow)
{
checkModel.CheckShow = false;
}
else
{
checkModel.CheckShow = true;
}
}
}
Xaml代码如下:
<ContentPage.Content>
<StackLayout x:Name="ContentPage">
<Label Text="Welcome to Xamarin.Forms!"
VerticalOptions="Start"
HorizontalOptions="CenterAndExpand" />
<Button Text="ShowOrNo" Clicked="Button_Clicked"/>
<ListView ItemsSource="{Binding NewOrders}"
x:Name="lstNewOrders"
RowHeight="80">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid BackgroundColor="#fefefe"
Padding="10"
x:Name="grid">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="60"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="30"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="auto"></RowDefinition>
</Grid.RowDefinitions>
<Image Source="bluecircle.png"
Grid.Column="0"
Grid.Row="0"
VerticalOptions="Start"></Image>
<Grid Grid.Column="1"
Grid.Row="0"
Margin="0,5"
VerticalOptions="Center">
<Grid.RowDefinitions>
<RowDefinition Height="20"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Label Text="{Binding Number}"
FontAttributes="Bold"
Grid.Column="0"
Grid.Row="0"
FontSize="18"
x:Name="lblNumber" />
<Label Text="{Binding Description}"
Grid.Column="0"
Grid.Row="1"
FontSize="12" />
</Grid>
<CheckBox IsChecked="{Binding IsChecked}"
Grid.Column="2"
VerticalOptions="Center"
Grid.Row="0"
x:Name="chklstNew"
IsVisible="{Binding Source={x:Reference ContentPage},Path=BindingContext.CheckShow}"/>
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage.Content>
您将看到 CheckBox 的IsVisible
绑定到 ContentPage 的BindingContext
。
效果:
另一种方法是为单元格项目模型声明IsShow
属性。
例如,列表视图单元格模型为:
public class CheckItem : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public string Number { set; get; }
public string Description { set; get; }
private bool checkIsShow;
public bool CheckIsShow
{
set
{
if (checkIsShow != value)
{
checkIsShow = value;
OnPropertyChanged("CheckIsShow");
}
}
get
{
return checkIsShow;
}
}
private bool isChecked;
public bool IsChecked
{
set
{
if (isChecked != value)
{
isChecked = value;
OnPropertyChanged("IsChecked");
}
}
get
{
return isChecked;
}
}
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this,new PropertyChangedEventArgs(propertyName));
}
}
然后将ViewModel修改如下:
public class CheckModel
{
public List<CheckItem> NewOrders { get; set; }
public CheckModel()
{
NewOrders = new List<CheckItem>();
NewOrders.Add(new CheckItem() { Number = "1",Description = "1 description",CheckIsShow = false });
NewOrders.Add(new CheckItem() { Number = "2",Description = "2 description",CheckIsShow = false });
NewOrders.Add(new CheckItem() { Number = "3",Description = "3 description",CheckIsShow = false });
NewOrders.Add(new CheckItem() { Number = "4",Description = "4 description",CheckIsShow = false });
NewOrders.Add(new CheckItem() { Number = "5",Description = "5 description",CheckIsShow = false });
}
}
Xaml 代码,仅按如下所示修改CheckBox
代码:
...
<CheckBox IsChecked="{Binding IsChecked}"
Grid.Column="2"
VerticalOptions="Center"
Grid.Row="0"
x:Name="chklstNew"
IsVisible="{Binding CheckIsShow}"/>
...
现在ContentPage如下:
public partial class PageListViewCheckBox : ContentPage
{
CheckModel checkModel;
public PageListViewCheckBox()
{
InitializeComponent();
checkModel = new CheckModel();
BindingContext = checkModel;
}
private void Button_Clicked(object sender,EventArgs e)
{
foreach(var item in checkModel.NewOrders)
{
if (item.CheckIsShow)
{
item.CheckIsShow = false;
}
else
{
item.CheckIsShow = true;
}
}
}
效果与上面相同。
注意:在这里,您会看到 CheckBox 的IsChecked
也已绑定到ViewModel。这有助于了解使用MVVM
选择了哪个项目。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。