如何在 ListView 中选择一条记录并在代码隐藏方法中引用它? [英] How can I select a record in a ListView and reference it in the code behind method?
问题描述
我在 ListView
的 SQLite 数据库中列出了我的 ListItem
表中的记录,每条记录都是它自己的按钮,这会导致 EditItem
方法.我想要在这个方法中做的是将 ListItem
的布尔 Large
属性设置为 false
,但是我在获取相应的ListItem
作为变量.
I'm listing records from my ListItem
tables in my SQLite database in a ListView
, and each record is its own button, which leads to an EditItem
method. All I want to do in this method is set the boolean Large
attribute for the ListItem
to false
, but I'm having trouble getting the corresponding ListItem
as a variable.
使用我当前的代码,我得到的错误是:
With my current code, the error I'm getting is:
错误 CS0266 无法将类型对象"隐式转换为'Myapp.Models.ListItem'.存在显式转换(您是缺少演员表?)
Error CS0266 Cannot implicitly convert type 'object' to 'Myapp.Models.ListItem'. An explicit conversion exists (are you missing a cast?)
在我的代码后面获取和更新所选记录的正确方法是什么?
What's the correct way to get and update the selected record in my code behind?
我尝试在我的按钮上使用命令,现在我没有收到任何错误,但是甚至没有调用 EditItem
方法.我现在知道如何使用 Command
属性传递参数,但我不确定如何使用它调用方法.我知道如何使用 Clicked
属性调用方法,但我不知道如何使用它传递参数.
I tried using a Command with my button, and now I don't get any errors, but the EditItem
method isn't even called. I now know how to pass parameters with the Command
property, but I'm not sure how to call a method with it. I know how to call a method with the Clicked
property, but I don't know how to pass parameters with it.
Xaml:
<ListView>
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout>
<Button Text="{Binding Name}" Command="EditItem" CommandParameters="{Binding}" VerticalOptions="Start"/>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
背后的C#代码:
public async void EditItem(object sender, EventArgs e)
{
ListItem item = (ItemList)sender as ItemList;
item.Large = false;
...
}
我在 Xamarin.forms 应用中使用 sqlite-net-pcl Nuget 包.
I'm using the sqlite-net-pcl Nuget package in a Xamarin.forms app.
推荐答案
Try ListItem item = (ListItem)e.SelectedItem;
.
现在你正试图将一个通用的 object
分配给一个 ListItem
类型,你应该告诉它它是什么类型.
Right now you are trying to assign a generic object
to a ListItem
type, you should tell it what type it is.
您可能需要一些保护措施以确保它实际上是一个 ListItem
对象.即:
You probably want some safeguards in there to make sure it is actually a ListItem
object. I.e.:
var selectedListItem = e.SelectedItem as ListItem;
if (selectedListItem == null)
{
// TODO inform user or something
return;
}
根据您的评论,我会根据您的要求进行详细说明.对于您想要执行的操作,最好使用 Button
上的 Command
和 CommandParameter
.这里有一点需要注意.对于 Button
上的 Command
,您可能希望从您的视图模型中执行代码.但是一个 ViewCell
内的范围是一个 ListItem
的范围.要确保在正确的位置搜索 Command
,请为 Page
命名,例如:<ContentPage xmlns="..." x:Name="MyPage">
.
In accordance with what you are looking for according to your comments, I will elaborate a bit more. For what you want to do, its best to use the Command
and CommandParameter
on the Button
. There is one thing to note here. For the Command
on the Button
, you probably want to execute code from your view model. But the scope within one ViewCell
is that of a ListItem
. To make sure the Command
is being searched for in the right place, give the Page
a name, i.e. like this: <ContentPage xmlns="..." x:Name="MyPage">
.
现在从 Button
开始:<Button Text="{Binding Name}" Command="{Binding Source={x:Reference MyPage}, Path=BindingContext.EditItem}" CommandParameters="{Binding .}" VerticalOptions="Start"/>
.这告诉按钮将 Command
的绑定源设置为名称为 MyPage
的页面.然后将绑定的实际来源设置为 BindingContext.EditItem
属性.如果您不使用单独的视图模型而只是使用代码隐藏,请省略 BindingContext.
部分.
Now from the Button
go like this: <Button Text="{Binding Name}" Command="{Binding Source={x:Reference MyPage}, Path=BindingContext.EditItem}" CommandParameters="{Binding .}" VerticalOptions="Start"/>
. This tells the button to set the source of the binding for the Command
to the page with name MyPage
. The actual source of the binding is then set to the BindingContext.EditItem
property. If you're not using a separate view model but just use the code-behind, omit the BindingContext.
part.
您需要做的最后一件事是添加实际的Command
.在您的视图模型中(或在代码隐藏中)添加一个属性: public Command EditItem { get;设置;}
并在构造函数中添加可执行代码或您想如何初始化它:
The last thing you need to do is add the actual Command
. In your view model (or in the code-behind) add a property: public Command EditItem { get; set; }
and add the executable code in the constructor or how else you would like to initialize it:
public MyPage()
{
EditItem = new Command((parameter) => {
ListItem item = (ItemList)parameter as ItemList;
if (item == null)
return; // TODO error handling
item.Large = false;
});
}
因为 Button
上的 BindingParameter
设置为 .
,这意味着它绑定到后面的实际对象ViewCell
,您将检索ListItem
作为参数.
Because of the BindingParameter
on your Button
, which is set to .
, meaning that it is bound to the actual object that is behind that ViewCell
, you will retrieve the ListItem
as the parameter.
您可能希望将 Command
代码移动到一个单独的方法中以提高可读性.希望这是有道理的.
You probably want to move the Command
code into a separate method for readability. Hope this makes sense.
这篇关于如何在 ListView 中选择一条记录并在代码隐藏方法中引用它?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!