在 UWP 中更改 属性 后视图未更新
View not updating after property change in UWP
我正在尝试显示通过 API 调用获得的一些数据。
但是数据没有显示在应用程序中。
我正在使用 INotifyPropertyChanged 接口。
我的xaml.cs代码:
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));
}
我的xaml代码:
<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>
以下控件不会显示请求的数据。
<TextBlock Text="{x:Bind TravelList.Listname}"></TextBlock>
<Image Source="{x:Bind TravelList.imageLocation}"></Image>
API调用没有问题,数据设置到TravelList对象。
如果想在属性变化后更新控件,需要在TravelList
class中添加INotifyPropertyChanged
接口通知class的属性变化=13=] class。您可以在 TravelListDetail
的泛型 Set()
方法处添加一个断点,并查看当 _travelList
的值发生变化时,不会触发泛型 Set()
方法。注意,{x:Bind}扩展的默认模式是OneTime,你需要使用OneWay 模式 {x:Bind} 扩展。
您可以查看以下代码:
.xaml.cs 代码:
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 代码:
<Image Source="{x:Bind TravelList.ImageLocation,,Mode=OneWay}"></Image>
<TextBlock Text="{x:Bind TravelList.Listname,Mode=OneWay}"></TextBlock>
好吧,答案很简单。
我写的代码是正确的我只是忘了在 {x:Bind} 扩展中添加单向模式,就像@YanGu - MSFT 指出的那样。
我正在尝试显示通过 API 调用获得的一些数据。 但是数据没有显示在应用程序中。 我正在使用 INotifyPropertyChanged 接口。
我的xaml.cs代码:
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));
}
我的xaml代码:
<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>
以下控件不会显示请求的数据。
<TextBlock Text="{x:Bind TravelList.Listname}"></TextBlock>
<Image Source="{x:Bind TravelList.imageLocation}"></Image>
API调用没有问题,数据设置到TravelList对象。
如果想在属性变化后更新控件,需要在TravelList
class中添加INotifyPropertyChanged
接口通知class的属性变化=13=] class。您可以在 TravelListDetail
的泛型 Set()
方法处添加一个断点,并查看当 _travelList
的值发生变化时,不会触发泛型 Set()
方法。注意,{x:Bind}扩展的默认模式是OneTime,你需要使用OneWay 模式 {x:Bind} 扩展。
您可以查看以下代码:
.xaml.cs 代码:
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 代码:
<Image Source="{x:Bind TravelList.ImageLocation,,Mode=OneWay}"></Image>
<TextBlock Text="{x:Bind TravelList.Listname,Mode=OneWay}"></TextBlock>
好吧,答案很简单。 我写的代码是正确的我只是忘了在 {x:Bind} 扩展中添加单向模式,就像@YanGu - MSFT 指出的那样。