OnPropertyChanged 未更新用于 xamarin 的 xzing 条码扫描器的 UI
Posted
技术标签:
【中文标题】OnPropertyChanged 未更新用于 xamarin 的 xzing 条码扫描器的 UI【英文标题】:OnPropertyChanged not updating UI for xzing barcode scanner for xamarin 【发布时间】:2021-01-27 23:47:48 【问题描述】:我正在使用 mvvm,但我的应用程序和数据绑定和属性更改在应用程序的其他任何地方都有效,但出于某种原因,在我使用 XZing 条形码扫描仪的视图中,我的视图在扫描项目后没有更新。
我习惯于使用 XAML ViewModel 和 Codebehind,但我设置条形码扫描仪的方式只有 ViewModel 和 Codebehind/单独类。所以也许我错过了一些我不习惯做的简单事情。
我在下面发布了一些代码,它只是未更新属性之一的示例,productsLable.Text 的 PartName。它在页面首次加载并且虚拟 PartName 正确显示时绑定,但在扫描新项目后,我更新了 ViewModel 中的 ScannedPart 但在我设置并调用 OnPropertyChanged() 后从未调用过“get”;
这在我的应用程序的其他部分运行良好,但也许我在这里遗漏了一些愚蠢的东西,就像我说过我更喜欢在 XAML 中使用绑定一样。你看到我做错了什么或遗漏了什么吗?
提前致谢。
public class TimsCustomScanPage : ContentPage
ZXingScannerView zxing;
TimsCustomOverlay overlay;
RequestPartsViewModel viewModel;
public TimsCustomScanPage(RequestPartsViewModel viewModel) : base()
//Attaching ViewModel
this.viewModel = viewModel;
this.BindingContext = viewModel;
//Scanner found barcode
zxing.OnScanResult += (result) =>
// Stop analysis until we navigate away so we don't keep reading barcodes
zxing.IsAnalyzing = false;
//Setting new scanned part
viewModel.ScannedPart = viewModel.Parts.FirstOrDefault();
;
--Some more code--
var productsLabel = new Label()
//Text = "Find New Part",
TextColor = Color.Black,
WidthRequest = 150,
HorizontalOptions = LayoutOptions.Start,
VerticalTextAlignment = TextAlignment.Center,
Padding = new Thickness(0, 0, 0, 0),
;
//Binding text property
productsLabel.SetBinding(Label.TextProperty, "PartName");
productsLabel.BindingContext = viewModel.ScannedPart;
视图模型
public class RequestPartsViewModel : BaseViewModel
public ObservableCollection<TimsCategory> Categories get; set;
public ObservableCollection<TimsCategory> FavoriteCategories get; set;
public ObservableCollection<TimsPart> Parts get; set;
public TimsCategory CurrentSelection get; set;
public Command LoadItemsCommand get; set;
TimsPart scannedPart;
string partName;
int totalRequestedParts;
public RequestPartsViewModel()
Title = "Request Parts";
Categories = new ObservableCollection<TimsCategory>(db.Table<TimsCategory>().ToList());
Parts = new ObservableCollection<TimsPart>(db.Table<TimsPart>().ToList());
TotalRequestedParts = 0;
ScannedPart = new TimsPart();
ScannedPart.PartName = "Scan New Part";
ScannedPart.AvailableQuantity = 0;
//Attach parts to categories
foreach (var item in Categories)
int newId = item.CategoryId;
var partsForCategories = Parts.Where(p => p.CategoryId == newId);
var partsForCategoriesCollection = new ObservableCollection<TimsPart>(partsForCategories);
item.Parts = partsForCategoriesCollection;
FavoriteCategories = new ObservableCollection<TimsCategory>(Categories.Take(6).ToList());
LoadItemsCommand = new Command(async () => await ExecuteLoadItemsCommand());
public TimsPart ScannedPart
get
return scannedPart;
set
if (scannedPart != value)
scannedPart = value;
OnPropertyChanged("PartName");
OnPropertyChanged("RequestedQuantity");
OnPropertyChanged("AvailableQuantity");
OnPropertyChanged("ScannedPart");
基础视图模型
public class BaseViewModel : INotifyPropertyChanged
public SQLiteConnection db = TimsData.database;
bool isBusy = false;
public bool IsBusy
get return isBusy;
set SetProperty(ref isBusy, value);
string title = string.Empty;
public string Title
get return title;
set SetProperty(ref title, value);
protected bool SetProperty<T>(ref T backingStore, T value,
[CallerMemberName]string propertyName = "",
Action onChanged = null)
if (EqualityComparer<T>.Default.Equals(backingStore, value))
return false;
backingStore = value;
onChanged?.Invoke();
OnPropertyChanged(propertyName);
return true;
#region INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string propertyName = "")
var changed = PropertyChanged;
if (changed == null)
return;
changed.Invoke(this, new PropertyChangedEventArgs(propertyName));
#endregion
【问题讨论】:
【参考方案1】:我认为问题在于您直接绑定到一个属性,然后更改了基础对象,而不仅仅是属性。试试这个
productsLabel.SetBinding(Label.TextProperty, "ScannedPart.PartName");
// you already have a BindingContext set for your page that the Label will inherit
// productsLabel.BindingContext = viewModel.ScannedPart;
【讨论】:
以上是关于OnPropertyChanged 未更新用于 xamarin 的 xzing 条码扫描器的 UI的主要内容,如果未能解决你的问题,请参考以下文章
仅查看Model OnPropertyChanged上的更新,但不查看ViewModel OnPropertyChanged中的更新
WPF:多重绑定不使用 OnPropertyChanged 更新?
在不触发 OnPropertyChanged 的情况下更新 WPF DataGrid