pse*_*ote 0 c# listview observablecollection xamarin xamarin.forms
我在 XAML 中有一个 ListView,它绑定到 ViewModel 中的 ObservableCollection。初始化或 OnAppearing() 后,ListView 项目将完美显示。
但是,当我尝试从页面内(通过 ViewModel)更新 ListView 项目时,项目已更新,但旧项目仍然存在。
基本上,新项目将添加到 ListView 中,但位于之前 ObservableCollection 中的项目下方。我已经实现了 INotifyPropertyChanged 并且我认为我已经完成了所有正确的操作(尽管显然不是)。
请告诉我我做错了什么。我已经在 Collection 上尝试过 Clear() 但无济于事(相同的结果)。
基本视图模型:
public class BaseViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
protected void SetValue<T>(ref T backingField, T value, [CallerMemberName] string propertyName = null)
{
if (EqualityComparer<T>.Default.Equals(backingField, value))
return;
backingField = value;
OnPropertyChanged(propertyName);
}
}
Run Code Online (Sandbox Code Playgroud)
XAML:
<ListView IsEnabled="{Binding IsLoadingTable, Converter={Helpers:InverseBoolConverter}}"
IsVisible="{Binding IsLoadingTable, Converter={Helpers:InverseBoolConverter}}"
ItemsSource="{Binding LeagueStandings}"
SelectedItem="{Binding SelectedTeam, Mode=TwoWay}"
ItemSelected="ListView_ItemSelected"
RowHeight="60"
SeparatorVisibility="Default"
SeparatorColor="{DynamicResource accentColor}">
Run Code Online (Sandbox Code Playgroud)
页面.cs:
protected override void OnAppearing()
{
base.OnAppearing();
ViewModel.LoadLeagueStandingsCommand.Execute(_divisionId);
ViewModel.LoadPickerItemsCommand.Execute(null);
}
Run Code Online (Sandbox Code Playgroud)
视图模型初始化:
private ObservableCollection<Standing> _leagueStandings;
public ObservableCollection<Standing> LeagueStandings
{
get { return _leagueStandings ?? (_leagueStandings = new ObservableCollection<Standing>()); }
set { SetValue(ref _leagueStandings, value); }
}
Run Code Online (Sandbox Code Playgroud)
视图模型方法:
private async Task LoadLeagueStandings(string divId)
{
if (_hasLoadedStandings)
return;
if (IsLoadingTable)
return;
_hasLoadedStandings = true;
_divisionId = divId;
try
{
IsLoadingTable = true;
await _pageService.DisplayAlert("loading Selected", _divisionId, "ok");
var v = await GetLeagueTableAsync(_htmlParser, _divisionId);
LeagueStandings = new ObservableCollection<Standing>(v);
}
catch (Exception)
{
System.Diagnostics.Debug.WriteLine("Exception caught in DivisionsViewModel.cs.(LoadLeagueStandings).");
}
finally
{
IsLoadingTable = false;
}
}
Run Code Online (Sandbox Code Playgroud)
当 Picker 项发生变化时调用 ViewModel 方法:
private async Task SelectItem(string item)
{
if (item == null)
return;
SelectedItem = null;
var id = await _divisionFinder.GetDivisionIdAsync(item);
var v = await GetLeagueTableAsync(_htmlParser, id);
LeagueStandings = new ObservableCollection<Standing>(v);
}
Run Code Online (Sandbox Code Playgroud)
编辑* - 结果图片。第一个集合以数字 5 结束,新集合再次从 1 开始追加到列表视图的末尾。
编辑2:
public async Task<IEnumerable<Standing>> GetLeagueTableAsync(string divisionId)
{
// todo: get division Id from picker
string address = "";
if (IsOnline)
{
if (divisionId != "")
address = $"{BaseUrls.LeagueStandings}{divisionId}";
try
{
var config = Configuration.Default.WithDefaultLoader();
var document = await BrowsingContext.New(config).OpenAsync(address);
var cSelector = "table[class='table table-striped table-hover table-bordered'] tr";
var table = document.QuerySelectorAll(cSelector).Skip(1);
int count = 0;
foreach (var c in table)
{
var cells = c.QuerySelectorAll("td").ToArray();
_leagueStandings.Add(new Standing(++count, cells[0].TextContent.Trim(), cells[1].TextContent.Trim(),
cells[2].TextContent.Trim(), cells[3].TextContent.Trim(),
cells[4].TextContent.Trim(), cells[5].TextContent.Trim(),
cells[6].TextContent.Trim(), cells[7].TextContent.Trim()));
}
}
catch(Exception e)
{
System.Diagnostics.Debug.WriteLine($"\n\n Exception caught LoadingLeagueTable - {e} \n\n");
}
}
return _leagueStandings;
Run Code Online (Sandbox Code Playgroud)
由于您既不添加也不删除项目,并且要替换引用,因此您需要引发事件来告知视图已更改。将其替换为此代码,而不是您的代码
private ObservableCollection<Standing> _leagueStandings;
public ObservableCollection<Standing> LeagueStandings
{
get { return _leagueStandings; }
set {
_leagueStandings = value;
RaisePropertyChanged("LeagueStandings");
}
}
Run Code Online (Sandbox Code Playgroud)
另外,为了将来的参考,ObservableCollection已经实现了,INotifyPropertyChanged所以你不需要SetValue(x)..
| 归档时间: |
|
| 查看次数: |
7766 次 |
| 最近记录: |