我有一个班级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吗?
答案 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(); }
}
}