【发布时间】:2021-07-26 20:24:17
【问题描述】:
我刚开始使用 MVVM 布局,我的collectionView 列表中似乎无法显示任何内容。我相信这是我的绑定,不幸的是我真的不明白我应该如何绑定分组列表+ ViewModel。我读到绑定到没有源的路径,但我很确定我做错了。我已经检查过是否我什至可以加载共享,而我是,它们只是没有显示。
模型 -- 分享
[JsonProperty("iSpottedID")]
public int ID { get; set; }
[JsonProperty("sShoppingList")]
[MaxLength(255)]
public string ShoppingName { get; set; }
[JsonProperty("dtInfoUpdate")]
[MaxLength(20)]
public string CreateDate { get; set; }
[JsonProperty("iProductID")]
public int ProductID { get; set; }
[Indexed]
[JsonProperty("sLocation")]
[MaxLength(255)]
public string LocationName { get; set; }
[JsonProperty("tvCardJson")]
public string JsonString { get; set; }
ViewModel -- SharesViewModel 公共类 SharesViewModel : BaseViewModel { #region 属性
private int _id;
public int ID
{
get { return _id; }
set
{
SetValue(ref _id, value);
OnPropertyChanged(nameof(ID));
}
}
private string _longName;
public string LongName
{
get { return _longName; }
set
{
SetValue(ref _longName, value);
OnPropertyChanged(nameof(LongName));
}
}
private string _date;
public string CreateDate
{
get{ return _date;}
set
{
SetValue(ref _date, value);
OnPropertyChanged(nameof(CreateDate));
}
}
private int _prodID;
public int ProductID
{
get { return _id; }
set
{
SetValue(ref _prodID, value);
OnPropertyChanged(nameof(ProductID));
}
}
private string _json;
public string JsonString
{
get { return _json; }
set
{
SetValue(ref _json, value);
OnPropertyChanged(nameof(JsonString));
}
}
private string _location;
public string LocationName
{
get { return _location; }
set
{
SetValue(ref _location, value);
OnPropertyChanged(nameof(LocationName));
}
}
//ADD-ONS
public string Address
{
get
{
if (!string.IsNullOrEmpty(JsonString))
{
var jsonDict = JsonConvert.DeserializeObject<Dictionary<string, string>>(JsonString);
if (jsonDict.ContainsKey("address"))
if (jsonDict["address"] != "")
return jsonDict["address"];
}
return null;
}
}
private ImageSource _imageLink;
public ImageSource ImageLink
{
get
{
if(ProductID != 0)
{
...
return ImageSource.FromUri(link);
}
return null;
}
}
#endregion
public SharesViewModel(){}
public SharesViewModel(Share share)
{
ID = share.ID;
ProductID = share.ProductID;
JsonString = share.JsonString;
CreateDate = share.CreateDate;
LocationName = share.LocationName;
}
列表视图模型 -- SharesListViewlModel
public class SharesListViewModel : BaseViewModel
{
private SharesViewModel _selectedShare;
private bool _isDataLoaded;
//grouped list
public ObservableCollection<LocationSpotGroups<string, SharesViewModel>> Shares { get; set; }
...
public ICommand OpenMoreSharesCommand { get; private set; }
public ICommand LoadDataCommand { get; private set; }
public SharesListViewModel(Position NW , Position SE)
{
_nw = NW;
_se = SE;
LoadDataCommand = new Command(async () => await LoadData());
OpenMoreSharesCommand = new Command<SharesViewModel>(async (share) => await OpenMoreShares(share));
public ObservableCollection<SharesViewModel> sList { get; set; }
= new ObservableCollection<SharesViewModel>();
}
private async Task LoadData()
{
if (_isDataLoaded)
return;
var list = await _connection.GetAllRegionShares(_nw, _se);
foreach (var spot in list)
{
sList.Add(new SharesViewModel(spot));
}
var sorted = from item in sList
orderby item.LocationName
group item by item.LocationName into itemGroup
select new LocationSpotGroups<string, SharesViewModel>(itemGroup.Key, itemGroup);
Shares = new ObservableCollection<LocationSpotGroups<string, SharesViewModel>>(sorted);
}
LocationSpotGroups
public class LocationSpotGroups<K, T> : ObservableCollection<T>
{
public K GroupKey { get; set; }
public IEnumerable<T> GroupedItem { get; set; }
public LocationSpotGroups(K key, IEnumerable<T> shares)
{
GroupKey = key;
GroupedItem = shares;
foreach (var item in shares)
{
this.Items.Add(item);
}
}
}
SharesPage XAML
<CollectionView x:Name="CollectionList"
VerticalOptions="FillAndExpand"
ItemsSource="{Binding Shares}"
IsGrouped="True">
<!--HEADER-->
<CollectionView.GroupHeaderTemplate>
<DataTemplate>
<StackLayout Orientation="Horizontal"
Padding="5"
BackgroundColor="#f7f7fb">
<Label x:Name="labelname"
Text="{Binding GroupKey}"
HorizontalOptions="Start"
VerticalOptions="Center"
TextColor="gray" />
</StackLayout>
</DataTemplate>
</CollectionView.GroupHeaderTemplate>
<CollectionView.ItemsLayout>
<GridItemsLayout Orientation="Vertical" Span="2" />
</CollectionView.ItemsLayout>
<!--BODY-->
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid Padding="5" Margin="8">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="50" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<ImageButton Source="{Binding ImageLink}"
WidthRequest="150"
HeightRequest="150"
Grid.ColumnSpan="2"
CornerRadius="15"
Aspect="AspectFill"
Grid.Row="0"
Grid.Column="0"/>
<Label Text="{Binding ShoppingName}"
Grid.Row="1"
Grid.Column="0"/>
<Label Text="More"
Grid.Row="1"
Grid.Column="1"
HorizontalTextAlignment="End"/>
<Label Text="{Binding CreateDate}"
Grid.Row="2"
Grid.Column="0"/>
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
SharesPage CS
public SharesPage( Position NW, Position SE )
{
InitializeComponent();
ViewModel = new SharesListViewModel(NW, SE);
}
public SharesListViewModel ViewModel
{
get { return BindingContext as SharesListViewModel; }
set { BindingContext = value; }
}
protected override void OnAppearing()
{
ViewModel.LoadDataCommand.Execute(null);
base.OnAppearing();
}
【问题讨论】:
-
你可能需要在
Shares的setter中引发一个PropertyChanged事件 -
@Jason 我的绑定呢?他们做得对吗?运行我的代码时,我也没有收到错误。
-
它们看起来不错。但是您将 VM 分配给 BindingContext before
Shares已创建,因此您需要在发生这种情况时触发PropertyChanged以便 UI 知道要更新。如果您仍然遇到问题,我建议您从带有一个标签的简单非分组简历开始。首先让它工作,然后添加一个更复杂的模板。让它工作,然后修改它以使用分组数据。增量步骤 -
检查绑定的一种简单方法是在视图模型构造函数中向
Shares添加一些虚拟数据,例如what did to AnimalGroup here,然后试一试。 -
感谢@Shaw,问题是未设置共享。我做了一些测试数据,一切正常。现在我正在努力让 propertyChanged 之后被提升以设置数据。