【问题标题】:Binding to the ViewModel not working in Xamarin.Forms绑定到 ViewModel 在 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。

我做错了什么?

【问题讨论】:

  • 您的二传手似乎都没有致电PropertyChangedLoadCities 中的代码似乎引用了几个未定义的变量。这是剪切/粘贴错误,还是实际代码是这样的?您是否对其进行了调试以验证是否已加载数据?
  • LoadCities 中的未定义变量是剪切/粘贴错误,因为我试图将它们翻译成英文,regione 在代码中代表 Country。我需要修改和添加哪些setter PropertyChanged
  • 你正在绑定到CityList,所以你需要在设置时提高PropertyChanged
  • 成功了!感谢您的宝贵时间,这真的很有帮助!

标签: c# xaml xamarin xamarin.forms data-binding


【解决方案1】:

对于可能有同样问题的人,正如 xamarin 文档所说的那样

视图可访问的所有视图模型和模型类都应该 实现 INotifyPropertyChanged 接口。实现这个 视图模型或模型类中的接口允许该类提供 更改通知到视图中的任何数据绑定控件时, 基础属性值变化。

以下是关于 PropertyChanged 的​​更多提示:

-如果公共属性的值,总是引发 PropertyChanged 事件 变化。不要假设引发 PropertyChanged 事件可以 由于了解 XAML 绑定的发生方式而被忽略。

总是为任何计算属性引发 PropertyChanged 事件,其 值被视图模型或模型中的其他属性使用。

总是在方法结束时引发 PropertyChanged 事件 属性更改,或者当已知对象处于安全状态时。 引发事件通过调用事件的 处理程序同步。如果这发生在操作过程中, 它可能会在对象处于 不安全,部分更新的状态。此外,还可以 由 PropertyChanged 事件触发的级联更改。级联 更改通常需要在级联之前完成更新 更改可以安全执行。

永远不要引发 PropertyChanged 事件,如果 属性不变。这意味着你必须比较旧的 和引发 PropertyChanged 事件之前的新值。

从不提高 如果您是视图模型的构造函数期间的 PropertyChanged 事件 初始化一个属性。视图中的数据绑定控件不会有 订阅在此时接收更改通知。

从不 引发多个具有相同属性的 PropertyChanged 事件 在公共的单个同步调用中的名称参数 一个类的方法。例如,给定一个 NumberOfItems 属性,其 后备存储是 _numberOfItems 字段,如果方法递增 _numberOfItems 在循环执行期间 50 次,它应该只在 NumberOfItems 属性上引发属性更改通知 一次,在所有工作完成之后。对于异步方法,raise 每个给定属性名称的 PropertyChanged 事件 异步延续链的同步段。

【讨论】:

    猜你喜欢
    • 2017-11-02
    • 1970-01-01
    • 2017-08-12
    • 2022-01-01
    • 2020-09-24
    • 2020-02-06
    • 2018-12-09
    • 2019-04-29
    相关资源
    最近更新 更多