好吧,使用UWP模板10进入MVVM。我已经阅读了很多页面,虽然每个人都试图说它非常简单,但我仍然无法使其工作。
要将其置于上下文中,OCR正在图像上运行,我希望文本自动显示在文本框中。
这是我的模特:
public class TextProcessing
{
private string _ocrText;
public string OcrText
{
get { return _ocrText; }
set
{
_ocrText = value;
}
}
}
这是我的ViewModel:
public class ScanPageViewModel : ViewModelBase, INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private TextProcessing _ocrTextVM;
public ScanPageViewModel()
{
_ocrTextVM = new TextProcessing();
}
public TextProcessing OcrTextVM
{
get { return _ocrTextVM; }
set {
_ocrTextVM = value;
this.OnPropertyChanged("OcrTextVM");
}
}
public void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
这是我的观点:
<TextBox x:Name="rtbOcr"
Text="{Binding OcrTextVM.OcrText, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
首先,这不起作用。有人可以尝试显示我出错的地方吗?
然后,数据来自服务文件,服务如何更新该值?什么是正确的代码?
提前致谢。
答案 0 :(得分:2)
以下代码来自code.msdn(How to achieve MVVM design patterns in UWP),对您有所帮助:
逐步检查代码。
1.ViewModel实现了接口INotifyPropertyChanged,并在属性set方法中调用了PropertyChanged,如下所示:
public sealed class MainPageViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private string _productName;
public string ProductName
{
get { return _productName; }
set
{
_productName = value;
if (PropertyChanged != null)
{
PropertyChanged.Invoke(this, new PropertyChangedEventArgs(nameof(ProductName)));
}
}
}
}
2.在您的页面中初始化ViewMode,并将DataContext设置为ViewMode,如下所示:
public sealed partial class MainPage : Page
{
public MainPageViewModel ViewModel { get; set; } = new MainPageViewModel();
public MainPage()
{
...
this.DataContext = ViewModel;
}
}
3.在你的xaml中,绑定来自viewMode的数据,如下所示:
<TextBox Text="{Binding Path=ProductName,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Name="ProductNameTextBox" TextChanged="ProductNameTextBox_TextChanged" />
答案 1 :(得分:1)
由于您将构造函数中的值设置为其支持字段并绕过该属性,因此您的OnPropertyChanged
调用OcrTextVM实际上并未在您的情况下调用。
如果您通过属性设置值,它应该有效:
public ScanPageViewModel()
{
OcrTextVM = new TextProcessing();
}
当然,您的视图需要知道ScanPageViewModel
是其DataContext。最简单的方法是在您的视图的代码隐藏的构造函数中:
public OcrView()
{
DataContext = new ScanPageViewModel();
InitializeComponent();
}
假设你的OCR服务在使用时返回一个新的TextProcessing
对象,设置OcrTextVM的属性就足够了:
public class ScanPageViewModel : ViewModelBase, INotifyPropertyChanged
{
//...
private void GetOcrFromService()
{
//...
TextProcessing value = OcrService.Get();
OcrTextVM = value;
}
}
在注释中,OcrTextVM
名称并不能真正反映该属性正在做什么,因为它看起来并不像是一个视图模型。考虑重命名它。
答案 2 :(得分:1)
实际上,一旦我理解了,这很容易。这是更新TextBox.Text
所需的代码在模特中:
public class DisplayText : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private string _text;
public string Text
{
get { return _text; }
set
{
_text = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Text)));
}
}
}
在XAML文件中:
<TextBox Text="{Binding Helper.Text, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" ... />
在ViewModels中:
private DisplayText _helper = new DisplayText();
public DisplayText Helper
{
get { return _helper; }
set
{
_helper = value;
}
}
然后来自ViewModels的任何mod:
Helper.Text = "Whatever text, or method returning a string";