I'm having some issues binding my collection property in my viewmodel to a GridView. I'm using MVVM light and i believe i have the ViewModelLocator setup correctly and have the DataContext setup in the page's xaml.
Model
public class Base
{
public ObservableCollection<Downloads> results { get; set; }
}
public class Downloads
{
public int id { get; set; }
public string name { get; set; }
public int trackNumber { get; set; }
public string mixName { get; set; }
public string title { get; set; }
public string slug { get; set; }
public string releaseDate { get; set; }
public string publishDate { get; set; }
public List<Artist> artists { get; set; }
public string artistNames
{
get
{
return (artists == null)
? string.Empty
: string.Join(", ", artists.Select(a => a.name));
}
}
public string artistNamesSlug
{
get
{
return (artists == null)
? string.Empty
: string.Join("_", artists.Select(a => a.name));
}
}
public Release release { get; set; }
public Label label { get; set; }
public Image images { get; set; }
public int downloadId { get; set; }
public string audioFormat { get; set; }
public string downloadUrl { get; set; }
}
public class Release
{
public int id { get; set; }
public string name { get; set; }
public string type { get; set; }
public string slug { get; set; }
}
public class Label
{
public int id { get; set; }
public string name { get; set; }
public string type { get; set; }
public string slug { get; set; }
public bool status { get; set; }
}
public class Image
{
public LargeImage large { get; set; }
}
public class LargeImage
{
public int id { get; set; }
public int width { get; set; }
public int height { get; set; }
public string url { get; set; }
public string secureUrl { get; set; }
}
ViewModel
public class AvailableViewModel : ViewModelBase
{
public AvailableViewModel()
{
}
private Base availableDownloads;
public Base AvailableDownloads
{
get
{
if(availableDownloads == null)
{
GetData();
}
return availableDownloads;
}
set
{
availableDownloads = value;
RaisePropertyChanged(() => AvailableDownloads);
}
}
private async void GetData()
{
OAuth oauth = new OAuth();
string httpMethod = "GET";
string parameters = "status=available";
string response = await oauth.GetData(OAuth.availDownloadsUrl, httpMethod, parameters);
Base availableDownloads = JsonConvert.DeserializeObject<Base>(response);
}
}
XAML
DataContext="{Binding Available, Source={StaticResource Locator}}">
<Page.Resources>
<DataTemplate x:Key="AvailableGridView">
<Grid Margin="0,10,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="2*"/>
</Grid.ColumnDefinitions>
<Image Source="{Binding AvailableDownloads.images.large.url}" Grid.Column="0" />
<StackPanel Grid.Column="1" VerticalAlignment="Top" Margin="20,0,0,0">
<TextBlock Text="{Binding AvailableDownloads.title}" Style="{StaticResource BaseTextBlockStyle}" TextWrapping="Wrap"/>
<TextBlock Text="{Binding AvailableDownloads.release.name}" Style="{StaticResource BaseTextBlockStyle}"/>
<TextBlock Text="{Binding AvailableDownloads.artistNames}" Style="{StaticResource SubtitleTextBlockStyle}"/>
</StackPanel>
</Grid>
</DataTemplate>
</Page.Resources>
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<GridView ItemsSource="{Binding AvailableDownloads.results}" SelectionMode="Multiple" ItemTemplate="{StaticResource AvailableGridView}"/>
</Grid>
This might be part of the problem, but when i set the DataContext in the xaml the layout displays an Object Reference error. I don't know why that happens, but application will compile and run. I'm new to MVVM and i can't seem to figure out why my bindings aren't working here.
This might be part of the problem, but when i set the DataContext in the xaml the layout displays an Object Reference error.
Is this "Object Reference error" NullReferenceException error? Since your code it not comprehensive, I can reproduce this problem in several places, but I don't know which exactly causes your problem.
First I changed your XAML code for test here, and I used x:Bind in the DataTemplate
of GridView
:
...
DataContext="{Binding Available, Source={StaticResource Locator}}"
xmlns:model="using:[Namespace of your app].Model">
<Page.Resources>
<DataTemplate x:Key="AvailableGridView" x:DataType="model:Downloads">
<Grid Margin="0,10,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="2*" />
</Grid.ColumnDefinitions>
<!--<Image Source="{x:Bind downloadUrl}" Grid.Column="0" />-->
<StackPanel Grid.Column="1" VerticalAlignment="Top" Margin="20,0,0,0">
<TextBlock Text="{x:Bind title}" Style="{StaticResource BaseTextBlockStyle}" TextWrapping="Wrap" />
<TextBlock Text="{x:Bind release.name}" Style="{StaticResource BaseTextBlockStyle}" />
<TextBlock Text="{x:Bind artistNames}" Style="{StaticResource SubtitleTextBlockStyle}" />
</StackPanel>
</Grid>
</DataTemplate>
</Page.Resources>
<Grid>
<GridView ItemsSource="{Binding AvailableDownloads.results}" SelectionMode="Multiple" ItemTemplate="{StaticResource AvailableGridView}" />
</Grid>
And I changed your Base
class like this:
public class Base
{
public ObservableCollection<Downloads> results { get; set; }
public Base()
{
results = new ObservableCollection<Downloads>();
}
}
This could be a possible reason if you don't create a new instance of ObservableCollection<Downloads>
when you add data.
And I changed your AvailableViewModel()
like this, the data added into the result
are fake, just for testing:
public AvailableViewModel()
{
availableDownloads = new Base();
availableDownloads.results.Add(new Downloads { title = "11111", artistNames = "222", release = new Release(0, "333", "", "") });
availableDownloads.results.Add(new Downloads { title = "11111" });
availableDownloads.results.Add(new Downloads { title = "11111" });
availableDownloads.results.Add(new Downloads { title = "11111" });
availableDownloads.results.Add(new Downloads { title = "11111" });
}
As you can see, I created a new instance of Base
class here.
I noticed that in your xaml code you used release.name
, for this, I think you need to modify your Release
class like this:
public class Release
{
public Release()
{
}
public Release(int Id, string Name, string Type, string Slug)
{
this.id = Id;
this.name = Name;
this.type = Type;
this.slug = Slug;
}
public int id { get; set; }
public string name { get; set; }
public string type { get; set; }
public string slug { get; set; }
}
And you can create the instance of Release
class like this:
release = new Release(0, "333", "", "");
I commented the Image
control in your DataTemplate
, to do this work, you need modify your LargeImage
and Image
like the Release
class.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.