绑定到 ViewModel 在 Xamarin.Forms 中不起作用
Posted
技术标签:
【中文标题】绑定到 ViewModel 在 Xamarin.Forms 中不起作用【英文标题】:Binding to the ViewModel not working in Xamarin.Forms 【发布时间】:2022-01-14 03:13:51 【问题描述】:我正在尝试制作一个显示国家列表的应用程序,当单击一个国家/地区时,它会显示该国家/地区的城市列表。
Country.cs:
public class Country
public string Name get; set;
public ImageSource Image get; set;
public IList<City> Cities get; set;
City.cs:
public class City
public string Name get; set;
在 CountryPageViewModel.cs 中通过以下方式进行导航:
async void OnSelectedCountry(Country country)
if (country == null)
return;
await Shell.Current.GoToAsync($"nameof(CitiesPage)?nameof(CitiesViewModel.Name)=country.Name");
城市被加载到 CitiesViewModel.cs 中:
[QueryProperty(nameof(Name), nameof(Name))]
public class CitiesViewModel : BaseViewModel
private string countryName;
public IList<City> CityList get; set;
public string Name
get
return countryName;
set
countryName = value;
LoadCities(value);
public async void LoadCities(string countryName)
try
Country country = await DataStore.GetItemAsync(cityName);
IList<City> cities = country.Cities;
CityList = cities;
catch (Exception)
Console.WriteLine("Impossible to load cities");
在 XAML (CitiesPage.xaml) 中:
<CollectionView x:Name="citiesCollectionView" x:DataType="viewmodels:CitiesViewModel"
ItemsSource="Binding CityList"
EmptyView="Impossible to load cities" >
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid Padding="5" x:DataType="models:City">
<Frame Style="StaticResource CityCard">
<Grid RowDefinitions="Auto,Auto"
ColumnDefinitions="Auto" >
<Label Grid.Column="1"
Text="Binding Name"
FontAttributes="Bold"
VerticalTextAlignment="Center"
Padding="10"
HeightRequest="50" />
</Grid>
</Frame>
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
但“城市”页面中没有显示任何内容。我已将 CitiesPage.xaml.cs(代码隐藏)中的 BindingContext 设置为 ViewModel。
我做错了什么?
【问题讨论】:
您的二传手似乎都没有致电PropertyChanged
。 LoadCities
中的代码似乎引用了几个未定义的变量。这是剪切/粘贴错误,还是实际代码是这样的?您是否对其进行了调试以验证是否已加载数据?
LoadCities
中的未定义变量是剪切/粘贴错误,因为我试图将它们翻译成英文,regione
在代码中代表 Country
。我需要修改和添加哪些setter PropertyChanged
?
你正在绑定到CityList
,所以你需要在设置时提高PropertyChanged
成功了!感谢您的宝贵时间,这真的很有帮助!
【参考方案1】:
对于可能有同样问题的人,正如 xamarin 文档所说的那样
视图可访问的所有视图模型和模型类都应该 实现 INotifyPropertyChanged 接口。实现这个 视图模型或模型类中的接口允许该类提供 更改通知到视图中的任何数据绑定控件时, 基础属性值变化。
以下是关于 PropertyChanged 的更多提示:
-如果公共属性的值,总是引发 PropertyChanged 事件 变化。不要假设引发 PropertyChanged 事件可以 由于了解 XAML 绑定的发生方式而被忽略。
总是为任何计算属性引发 PropertyChanged 事件,其 值被视图模型或模型中的其他属性使用。
总是在方法结束时引发 PropertyChanged 事件 属性更改,或者当已知对象处于安全状态时。 引发事件通过调用事件的 处理程序同步。如果这发生在操作过程中, 它可能会在对象处于 不安全,部分更新的状态。此外,还可以 由 PropertyChanged 事件触发的级联更改。级联 更改通常需要在级联之前完成更新 更改可以安全执行。
永远不要引发 PropertyChanged 事件,如果 属性不变。这意味着你必须比较旧的 和引发 PropertyChanged 事件之前的新值。
从不提高 如果您是视图模型的构造函数期间的 PropertyChanged 事件 初始化一个属性。视图中的数据绑定控件不会有 订阅在此时接收更改通知。
从不 引发多个具有相同属性的 PropertyChanged 事件 在公共的单个同步调用中的名称参数 一个类的方法。例如,给定一个 NumberOfItems 属性,其 后备存储是 _numberOfItems 字段,如果方法递增 _numberOfItems 在循环执行期间 50 次,它应该只在 NumberOfItems 属性上引发属性更改通知 一次,在所有工作完成之后。对于异步方法,raise 每个给定属性名称的 PropertyChanged 事件 异步延续链的同步段。
【讨论】:
以上是关于绑定到 ViewModel 在 Xamarin.Forms 中不起作用的主要内容,如果未能解决你的问题,请参考以下文章
如何绑定到CarouselView(Xamarin.Forms)(MVVM)内部的ViewModel元素?
绑定到 ViewModel 在 Xamarin.Forms 中不起作用