【发布时间】:2018-01-22 03:03:40
【问题描述】:
我有一堂课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; }
}
我还有一个 ViewModel ProductVm 继承自 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,里面有一个包含按钮和图像的网格,如果product.IsFavorite 为false,则此图像加载pincturea.png,在其他情况下加载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 或 pinctureb.png)后,它会更新集合值以及 GUI
所以它会更新显示的图像
搜索的解决方案
经过搜索,我看到每个人都说这与一个
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 吗?
【问题讨论】:
标签: c# listview xamarin mvvm xamarin.forms