C# 无法使ListView显示初始选定项
似乎无法在Xamarin表单列表视图中显示初始选择。我看到这个问题被问了好几次,但是在每一个案例中,要么没有相关的答案,要么未回答的问题太复杂,无法正确分析,要么问题得到了回答,但答案不起作用。所以我想我会提出这个问题的简化版本,希望有人能给我一个解决办法。解决方法是所有可以做的事情,因为很明显SelectedItem不能绑定,也不能从代码中设置。以下是我所研究的问题 这是XAMLC# 无法使ListView显示初始选定项,c#,xamarin,xamarin.forms,C#,Xamarin,Xamarin.forms,似乎无法在Xamarin表单列表视图中显示初始选择。我看到这个问题被问了好几次,但是在每一个案例中,要么没有相关的答案,要么未回答的问题太复杂,无法正确分析,要么问题得到了回答,但答案不起作用。所以我想我会提出这个问题的简化版本,希望有人能给我一个解决办法。解决方法是所有可以做的事情,因为很明显SelectedItem不能绑定,也不能从代码中设置。以下是我所研究的问题 这是XAML <?xml version="1.0" encoding="utf-8" ?> <Con
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:XamarinFormsBench"
x:Class="XamarinFormsBench.ListViewPage1">
<ContentPage.BindingContext>
<local:ViewModel1/>
</ContentPage.BindingContext>
<ListView x:Name="MyListView" Margin="0,20,0,0"
ItemsSource="{Binding Items}" SelectedItem="{Binding SelectedItem, Mode=TwoWay}"
BindingContextChanged="MyListView_BindingContextChanged">
</ListView>
</ContentPage>
这是代码
public class Item
{
public Item(string name, string description)
{
Name = name;
Description = description;
}
string Name { get; set; }
string Description { get; set; }
public override string ToString()
{
return Name + " = " + Description;
}
}
public class ViewModel1 : INotifyPropertyChanged
{
public ObservableCollection<Item> Items { get; set; }
public ViewModel1()
{
Items = new ObservableCollection<Item>
{
new Item("Item 1","First item"),
new Item("Item 2","Second item"),
new Item("Item 3","Third item"),
new Item("Item 4","Fourth item"),
new Item("Item 5","Fifth item")
};
_selectedItem = Items[2];
}
Item _selectedItem;
public event PropertyChangedEventHandler PropertyChanged;
public Item SelectedItem
{
get
{
return _selectedItem;
}
set
{
_selectedItem = value;
NotifyPropertyChanged(nameof(SelectedItem));
}
}
public void NotifyPropertyChanged(string name)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
}
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class ListViewPage1 : ContentPage
{
public ListViewPage1()
{
InitializeComponent();
}
public ViewModel1 ViewModel
{
get
{
return BindingContext as ViewModel1;
}
}
private void MyListView_BindingContextChanged(object sender, EventArgs e)
{
// MyListView.SelectedItem = ViewModel.SelectedItem;
}
}
公共类项目
{
公共项(字符串名称、字符串描述)
{
名称=名称;
描述=描述;
}
字符串名称{get;set;}
字符串说明{get;set;}
公共重写字符串ToString()
{
返回名称+“=”+说明;
}
}
公共类ViewModel1:INotifyPropertyChanged
{
公共ObservableCollection项{get;set;}
公共视图模型1()
{
Items=新的ObservableCollection
{
新项目(“项目1”、“第一项”),
新项目(“项目2”、“第二项”),
新项目(“项目3”、“第三项”),
新项目(“项目4”、“第四项”),
新项目(“项目5”、“第五项”)
};
_selectedItem=Items[2];
}
项目_selectedItem;
公共事件属性更改事件处理程序属性更改;
公共项目选择项
{
得到
{
返回_selectedItem;
}
设置
{
_选择editem=值;
NotifyPropertyChanged(名称(SelectedItem));
}
}
public void NotifyPropertyChanged(字符串名称)
{
PropertyChanged?.Invoke(这是新的PropertyChangedEventArgs(名称));
}
}
[XamlCompilation(XamlCompilationOptions.Compile)]
公共部分类ListViewPage1:ContentPage
{
公共列表视图第1页()
{
初始化组件();
}
公共视图模型1视图模型
{
得到
{
将BindingContext返回为ViewModel1;
}
}
私有void MyListView\u BindingContextChanged(对象发送方,事件参数e)
{
//MyListView.SelectedItem=ViewModel.SelectedItem;
}
}
我的期望是出现5个项目的列表,第3个项目将突出显示。出现的情况是显示5个项目,但没有突出显示任何项目。绑定显然有效,因为每次单击某个项目时,所选项目都会更新
现在,如果我删除绑定,并尝试通过取消靠近末尾的行的注释来设置代码中的选定项,那么这也不起作用
所以我没有主意了。我一直在考虑模拟鼠标点击,但这确实是一个难题,超出了我的意愿
我已经在UWP和Android上运行了这段代码。我还没有尝试过iOS。我刚刚创建了一个快速测试解决方案,这一切在iOS和Android上都适用 不同之处在于,我使用FreshMvvm绑定视图和ViewModel,并使用PropertyChanged.Fody自动执行通知 这表明是您的绑定或属性更改导致了问题 这是viewmodel
[AddINotifyPropertyChangedInterface]
public class MainPageModel : FreshBasePageModel
{
public MainPageModel()
{
Items = new ObservableCollection<Item>
{
new Item("Item 1","First item"),
new Item("Item 2","Second item"),
new Item("Item 3","Third item"),
new Item("Item 4","Fourth item"),
new Item("Item 5","Fifth item")
};
SelectedItem = Items[2];
}
public ObservableCollection<Item> Items { get; set; }
public Item SelectedItem { get; set; }
}
[AddNotifyPropertyChangedInterface]
公共类MainPageModel:FreshBasePageModel
{
公共主页模型()
{
Items=新的ObservableCollection
{
新项目(“项目1”、“第一项”),
新项目(“项目2”、“第二项”),
新项目(“项目3”、“第三项”),
新项目(“项目4”、“第四项”),
新项目(“项目5”、“第五项”)
};
SelectedItem=Items[2];
}
公共ObservableCollection项{get;set;}
公共项SelectedItem{get;set;}
}
那景色呢
<?xml version="1.0" encoding="utf-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="ScratchPad.Pages.MainPage"
Title="List Test">
<ListView ItemsSource="{Binding Items}"
SelectedItem="{Binding SelectedItem, Mode=TwoWay}">
</ListView>
</ContentPage>
而App.xaml.cs只是为了更好的衡量
public partial class App : Application
{
public App()
{
InitializeComponent();
var page = FreshPageModelResolver.ResolvePageModel<MainPageModel>();
var nav = new FreshNavigationContainer(page);
MainPage = nav;
}
...
}
公共部分类应用程序:应用程序
{
公共应用程序()
{
初始化组件();
var page=FreshPageModelResolver.ResolvePageModel();
var nav=新的FreshNavigationContainer(第页);
主页=导航;
}
...
}
编辑“纯”Xamarin表单代码
这里是风景
<?xml version="1.0" encoding="utf-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:selectedItemTest="clr-namespace:SelectedItemTest;assembly=SelectedItemTest"
x:Class="SelectedItemTest.MainPage"
Title="List Test">
<ContentPage.BindingContext>
<selectedItemTest:MainPageModel/>
</ContentPage.BindingContext>
<ListView ItemsSource="{Binding Items}"
SelectedItem="{Binding SelectedItem, Mode=TwoWay}">
</ListView>
</ContentPage>
以及视图模型
public class MainPageModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public ObservableCollection<Item> Items { get; set; }
public MainPageModel()
{
Items = new ObservableCollection<Item>
{
new Item("Item 1","First item"),
new Item("Item 2","Second item"),
new Item("Item 3","Third item"),
new Item("Item 4","Fourth item"),
new Item("Item 5","Fifth item")
};
SelectedItem = Items[2];
}
private Item _selectedItem;
public Item SelectedItem
{
get
{
return _selectedItem;
}
set
{
_selectedItem = value;
OnPropertyChanged(nameof(SelectedItem));
}
}
}
public类MainPageModel:INotifyPropertyChanged
{
公共事件属性更改事件处理程序属性更改;
受保护的虚拟void OnPropertyChanged(字符串propertyName=null)
{
PropertyChanged?.Invoke(这是新的PropertyChangedEventArgs(propertyName));
}
公共ObservableCollection项{get;set;}
公共主页模型()
{
Items=新的ObservableCollection
{
新项目(“项目1”、“第一项”),
新项目(“项目2”、“第二项”),
新项目(“项目3”、“第三项”),
新项目(“项目4”、“第四项”),
新项目(“项目5”、“第五项”)
};
SelectedItem=Items[2];
}
私人物品_selectedItem;
公共项目选择项
{
得到
{
返回_selectedItem;
}
设置
{
_选择editem=值;
OnPropertyChanged(名称(SelectedItem));
}
}
}
你为什么不试试这样的东西:
List<TodoItem> items = await todoTable.OrderByDescending(todoItem => todoItem.CreatedAt).ToListAsync();
listView.Items.Clear();
if (items.Count > 0)
{
foreach (var item in items)
{
string row = "";
row += $"Name: {item.Text}" + $" created at {item.CreatedAt.ToLocalTime()}";
listView.Items.Add(row);
}
int selectedItem = 2;
if(items.Count > selectedItem)
listView.SelectedIndex = selectedItem;
}
List items=wait todoTable.OrderByDescending(todoItem=>todoItem.CreatedAt.toListSync();
listView.Items.Clear();
如果(items.Count>0)
{
foreach(项目中的var项目)
{
字符串行=”;
行+=$“名称:{item.Text}”+$“创建于{item.CreatedAt.ToLocalTime()}”;
listView.Items.Add(行);
}
我
protected override void OnAppearing()
{
base.OnAppearing();
// *STANDARD MASSIVE KLUGE* Needed to get initial selection to show.
Item m = MyListView.SelectedItem as Item;
MyListView.SelectedItem = null;
MyListView.SelectedItem = m;
}