Reputation: 41
I'm trying to display some data im getting via an API call. But the data is not showing in the application. Im using the INotifyPropertyChanged interface.
My xaml.cs code:
public sealed partial class TravelListDetail : Page, INotifyPropertyChanged
{
private TravelList _travelList;
public TravelList TravelList
{
get { return _travelList; }
set { Set(ref _travelList, value); }
}
HttpDataService http = new HttpDataService();
public TravelListDetail()
{
this.InitializeComponent();
}
protected override async void OnNavigatedTo(NavigationEventArgs e)
{
string s = "";
var id = e.Parameter;
Task task = Task.Run(async () =>
{
Windows.Storage.StorageFolder storageFolder = Windows.Storage.ApplicationData.Current.TemporaryFolder;
Windows.Storage.StorageFile currentUser = await storageFolder.GetFileAsync("currentUser");
s = await Windows.Storage.FileIO.ReadTextAsync(currentUser);
});
task.Wait(); // Wait
base.OnNavigatedTo(e);
var data = await http.GetAsync<TravelList>($"https://localhost:5001/api/TravelList/{id}", s);
TravelList = data;
TravelList.imageLocation = "../Assets/blank-aerial-beach-background-template_1308-28443.jpg";
}
protected override void OnNavigatingFrom(NavigatingCancelEventArgs e)
{
base.OnNavigatingFrom(e);
if (e.NavigationMode == NavigationMode.Back)
{
NavigationService.Frame.SetListDataItemForNextConnectedAnimation(TravelList);
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void Set<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
{
if (Equals(storage, value))
{
return;
}
storage = value;
OnPropertyChanged(propertyName);
}
private void OnPropertyChanged(string propertyName) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
My xaml code:
<Page
x:Class="TravelClient.Views.TravelListDetail"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:TravelClient.Views"
xmlns:controls="using:Microsoft.Toolkit.Uwp.UI.Controls"
xmlns:animations="using:Microsoft.Toolkit.Uwp.UI.Animations"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid x:Name="ContentArea">
<ScrollViewer>
<StackPanel>
<RelativePanel>
<Grid
x:Name="Thumbnail"
Width="200"
Height="200"
Margin="{StaticResource SmallRightMargin}"
Padding="{StaticResource XSmallLeftTopRightBottomMargin}"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Background="{ThemeResource SystemControlPageBackgroundChromeLowBrush}"
RelativePanel.AlignLeftWithPanel="True"
RelativePanel.AlignTopWithPanel="True">
<Image Source="{x:Bind TravelList.imageLocation}"></Image>
</Grid>
</RelativePanel>
<StackPanel>
<TextBlock Text="{x:Bind TravelList.Listname}"></TextBlock>
<TextBlock Text="test"></TextBlock>
</StackPanel>
</StackPanel>
</ScrollViewer>
</Grid>
</Page>
The following controls wont show the data that is requested.
<TextBlock Text="{x:Bind TravelList.Listname}"></TextBlock>
<Image Source="{x:Bind TravelList.imageLocation}"></Image>
There is no problem with the API call, the data is set to the TravelList object.
Upvotes: 0
Views: 1315
Reputation: 41
Okay so the answer was pretty simple. The code i wrote was corret I just forgot to add the OneWay mode in the {x:Bind} extension, like @YanGu - MSFT pointed out.
Upvotes: 0
Reputation: 3032
If you want to update controls after property changes, you need to add the INotifyPropertyChanged
interface to the TravelList
class to notify the changes of properties of TravelList
class. You could add a breakpoint at the generic Set()
method of TravelListDetail
and view that when the value of _travelList
changes, the generic Set()
method is not triggered. And note, the default mode of {x:Bind} extension is OneTime, you need to use OneWay mode in {x:Bind} extension.
You could check the following code:
.xaml.cs code:
public class TravelList: INotifyPropertyChanged
{
private string imageLocation;
public string ImageLocation
{
get { return imageLocation; }
set
{
Set(ref imageLocation, value);
}
}
private string listname;
public string Listname {
get { return listname; }
set
{
Set(ref listname, value);
}
}
private void Set<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
{
if (Equals(storage, value))
{
return;
}
storage = value;
OnPropertyChanged(propertyName);
}
public TravelList()
{
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
......
}
.xaml code:
<Image Source="{x:Bind TravelList.ImageLocation,,Mode=OneWay}"></Image>
<TextBlock Text="{x:Bind TravelList.Listname,Mode=OneWay}"></TextBlock>
Upvotes: 1