首页 > 解决方案 > Xamarin Forms ListView 绑定未更新

问题描述

我有个问题。我用 ViewModel 创建了一个 ListView。在我的 ListView 中,我有一些带有文本的标签,这些标签绑定到 ItemSource 中的对象。现在,当我更改 ObservableCollection 中项目的 ViewModel 中的值时,屏幕上没有任何变化!

这是我的视图模型:

public class VM_DeviceList : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;


    public ICommand cmdDeleteDevice
    {
        get
        {
            return new Command<int>((x) => DeleteDevice_Handler(x));
        }
    }

    public ICommand cmdTogglePower
    {
        get
        {
            return new Command<int>((x) => TogglePower_Handler(x));
        }
    }


    private ObservableCollection<DisplayedDevice> _knownDeviceList;
    public ObservableCollection<DisplayedDevice> knownDeviceList
    {
        get
        {
            return _knownDeviceList;
        }
        set
        {
            if (_knownDeviceList != value)
            {
                _knownDeviceList = value;

                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs("knownDeviceList"));
                }
            }
        }
    }

这是我的 ObservableCollection 类:

public class DisplayedDevice : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    public int Id { get; set; }
    public string Name { get; set; }
    public string State { get; set; }
    public string StateShown { get; set; }
    public string deviceImage { get; set; }
    public string Color { get; set; }
    public string PowerStateColor { get; set; }
    public string DeviceImageColor { get; set; }

    public string DeviceImage
    {
        get
        {
            return deviceImage;
        }

        set
        {
            deviceImage = value;
            OnPropertyChanged();
        }
    }
}

这是xaml:

<ListView ItemsSource="{Binding knownDeviceList}" SelectionMode="None" RowHeight="90" ItemTapped="device_Clicked" x:Name="MyListView">
    <ListView.ItemTemplate>
        <DataTemplate>
            <ViewCell>
                <AbsoluteLayout HeightRequest="70" Margin="20,10,20,10">
                    <StackLayout Opacity="0.3" BackgroundColor="White"
                        AbsoluteLayout.LayoutBounds="0,0,1,1" 
                        AbsoluteLayout.LayoutFlags="All" />
                    <StackLayout AbsoluteLayout.LayoutBounds="0,0,1,1" 
                        AbsoluteLayout.LayoutFlags="All">
                        <Grid RowSpacing="0">
                            <Grid.RowDefinitions>
                                <RowDefinition Height="35" />
                                <RowDefinition Height="35" />
                            </Grid.RowDefinitions>

                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="70" />
                                <ColumnDefinition Width="*" />
                                <ColumnDefinition Width="70" />
                            </Grid.ColumnDefinitions>

                            <Label Grid.Row="0" Grid.Column="1" Text="{Binding Name}" Margin="0,3,0,0"
                        FontAttributes="Bold" FontSize="24" TextColor="White" />
                            <Label Grid.Row="1" Grid.Column="1" Text="{Binding StateShown}" FontSize="18" TextColor="White" />

                            <!-- <Image Source="power" Grid.RowSpan="2" Grid.Column="2" Margin="5" /> -->
                            <controls:IconView x:Name="btnPower" Source="power" Grid.RowSpan="2" Grid.Column="2" Margin="5"
                                            Foreground="{Binding PowerStateColor}">
                                <controls:IconView.GestureRecognizers>
                                    <TapGestureRecognizer Command="{Binding Path=BindingContext.cmdTogglePower, Source={x:Reference MyListView}}" CommandParameter="{Binding Id}" />
                                </controls:IconView.GestureRecognizers>
                            </controls:IconView>
                        </Grid>
                    </StackLayout>
                </AbsoluteLayout>
            </ViewCell>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

现在我期望发生的是,当我单击 IconView 时,我更改了 IconView 颜色和带有 StateShown 绑定的标签。但是当我点击 IconView 时没有任何变化!

我究竟做错了什么?

标签: c#xamarinxamarin.formsxamarin.androidxamarin.ios

解决方案


您可以使用 MVVMHelpers NuGet 包并将 NuGet 中的 ObservableObject 类直接实现到 DisplayedDevice 类,并且您需要使用私有变量的引用来制作所有属性。

public class DisplayedDevice: ObservableObject
    {

        string _textField = string.Empty;
        public string TextField
        {
            get => _textField;
            set => SetProperty(ref _textField, value);
        }
        bool _isBarChartVisible = false;
        public bool IsBarChartVisible
        {
            get => _isBarChartVisible;
            set => SetProperty(ref _isBarChartVisible, value);
        }
}
}

每个公共财产都应该由相同类型的私有财产支持。这很重要,因此任何属性的任何更改都将使用 INotifyPropertyChanged 反映在 UI 上


推荐阅读