如何在Xamarin中的ViewModel中执行图像触发器后更新listView?

时间:2018-01-22 03:03:41

标签: c# listview xamarin mvvm xamarin.forms

我有一个班级Product

 public class Product:ObservableObject,  IKeyObject
    {
        [SQLite.PrimaryKey]
        public string Id { get; set; }     //this is cause i am using sqlite
        //other properties
        public bool IsFavorite { get; set; }        
    }

我还有一个继承自ProductVm ViewModel BaseViewModel,此类BaseViewModel继承自ObservableObject

public abstract class BaseViewModel : ObservableObject
{
    protected INavigation Navigation;

    private bool _isBusy;
    public bool IsBusy
    {
        get => _isBusy;
        set { _isBusy = value; OnPropertyChanged(); }
    }
    protected BaseViewModel(INavigation navigation)
    {
        this.Navigation = navigation;
    }
    protected BaseViewModel()
    {
    }        
}


public abstract class ObservableObject : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged = delegate { };

    public void OnPropertyChanged([CallerMemberName] string name = "")
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
    }
}

现在, ViewModel Product有一个ObservableCollection<Product> 和一个命令 在页面PageProduct内,有一个视图模型的绑定,因此可以根据listView ProductResults上的更改来更新列表

public class ProductVm : BaseViewModel
{
    private ObservableCollection<Product> _productResults = new ObservableCollection<Product>();
    public ObservableCollection<Product> ProductResults
    {
        get => _productResults ;
        set {  _productResults = value; OnPropertyChanged(); }
    }
    public ICommand FavoriteProductCommand
    {
        get;
        set;
    }
    private void FavoriteProduct(Product product)
    {
        //here I tried traversing the  ObservableCollection<Product> 
        // and then update the value with the product.IsFavorite value
        //the item gets updated but the GUI does not    
        var item = _productResults.FirstOrDefault(i => i.Id == product.Id);
        if (item != null)
        {
            item.IsFavorite = product.IsFavorite;
        }
    }
    public ProductVm()
    {
        FavoriteProductCommand= new Command<Product>(FavoriteProduct);
    }

现在位于 PageProduct (名为MyProductPage,因此我可以使用命令并在ViewModel中传递产品对象)我有 listView ProductFeed,里面有一个包含按钮和图像的网格,如果pincturea.png false ,此图片会加载product.IsFavorite,在其他情况下会加载pinctureb.png我这样做通过使用触发器:

           <ListView x:Name="ProductFeed"
                  HasUnevenRows="true"
                  ItemsSource="{Binding ProductResults}">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                     <Grid WidthRequest="30"
                                      HeightRequest="30">                                        
                                    <Image BackgroundColor="Transparent"
                                           IsOpaque="True"
                                           x:Name="ImgFavorite"
                                           >
                                        <Image.Triggers>
                                            <DataTrigger TargetType="Image"
                                                         Binding="{Binding IsFavorite}" 
                                                         Value="false">
                                                <Setter Property="Source"
                                                        Value="pincturea.png" />
                                            </DataTrigger>
                                            <DataTrigger TargetType="Image"
                                                         Binding="{Binding IsFavorite} "
                                                         Value="true">
                                                <Setter Property="Source"
                                                        Value="pictureb.png" />
                                            </DataTrigger>
                                        </Image.Triggers>

                                    </Image>
                                    <Button
                                        Command="{Binding Path=BindingContext.FavoriteProductCommand, Source={x:Reference MyProductPage}}" CommandParameter="{Binding .}"
                                        BackgroundColor="Transparent"
                                        BorderColor="Transparent"
                                        Opacity="0.1">
                                    </Button>
                                </Grid>

                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>

问题

我希望在用户点击显示的按钮(显示pincturea.png o pinctureb.png)后,它会更新集合值以及GUI 所以它更新了显示的图像

搜索解决方案

搜索后,我看到每个人都说它与a有关 INotifyPropertyChanged问题,但据我所知,我已经做了那个部分 这样做

 public class ProductVm : BaseViewModel

并宣布

private ObservableCollection<Product> _productResults = new ObservableCollection<Product>();
        public ObservableCollection<Product> ProductResults
        {
            get => _productResults ;
            set {  _productResults = value; OnPropertyChanged(); }
        }

其他解决方案包括:

listview.isRefreshing = true;
//update observableCollection
listview.isRefreshing = false;

但是当我在使用ViewModel时,我无法访问listview ..

我缺少什么,所以在我的方法中

private void FavoriteProduct(Product product)

我也可以更新GUI吗?

1 个答案:

答案 0 :(得分:1)

您没有在模型中更改属性

试试这个

public class Product:ObservableObject,  IKeyObject
    {
        [SQLite.PrimaryKey]
        public string Id { get; set; }     //this is cause i am using sqlite
        //other properties
        private bool _isFavorite;
        public bool IsFavorite
        {
          get => _ isFavorite;
          set { _ isFavorite = value; OnPropertyChanged(); }
        } 

    }