C# 无法使ListView显示初始选定项

C# 无法使ListView显示初始选定项,c#,xamarin,xamarin.forms,C#,Xamarin,Xamarin.forms,似乎无法在Xamarin表单列表视图中显示初始选择。我看到这个问题被问了好几次,但是在每一个案例中,要么没有相关的答案,要么未回答的问题太复杂,无法正确分析,要么问题得到了回答,但答案不起作用。所以我想我会提出这个问题的简化版本,希望有人能给我一个解决办法。解决方法是所有可以做的事情,因为很明显SelectedItem不能绑定,也不能从代码中设置。以下是我所研究的问题 这是XAML <?xml version="1.0" encoding="utf-8" ?> <Con

似乎无法在Xamarin表单列表视图中显示初始选择。我看到这个问题被问了好几次,但是在每一个案例中,要么没有相关的答案,要么未回答的问题太复杂,无法正确分析,要么问题得到了回答,但答案不起作用。所以我想我会提出这个问题的简化版本,希望有人能给我一个解决办法。解决方法是所有可以做的事情,因为很明显SelectedItem不能绑定,也不能从代码中设置。以下是我所研究的问题

这是XAML

<?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;
    }