Xamarin 条目绑定到 MVVM
Posted
技术标签:
【中文标题】Xamarin 条目绑定到 MVVM【英文标题】:Xamarin Entry Binding to MVVM 【发布时间】:2021-10-16 10:22:34 【问题描述】:我正在尝试使用 MVVM 而不是背后的代码来实现我所能做的一切,但如果我有很多对象需要在条目更改时访问,我根本不知道如何做好。
Xaml:
<Entry x:Name="UpdatedCost"
TextChanged="UpdatedCost_TextChanged"/>
<Label x:Name="PriceDifLabel"/>
<Entry x:Name="CurrentCost"
Text="2.5"/>
<Entry x:Name="CurPriceUpdatedCostProfit"
Text="22%"/>
代码隐藏:
private void UpdatedCost_TextChanged(object sender, TextChangedEventArgs e)
if (double.TryParse(e.NewTextValue, out double UpdatedCost))
double diff = UpdatedCost - double.Parse(CurrentCost.Text);
string sign = diff > 0 ? "+" : "";
PriceDifLabel.Text = "(" + sign + string.Format("0:0.0", diff) +")";
PriceDifLabel.TextColor = diff > 0 ? Color.Red : Color.Green;
PriceDifLabel.BackgroundColor = Color.Yellow;
CurPriceUpdatedCostProfit.Text = ((int)((double.Parse(CurrentPrice.Text) - UpdatedCost) /
double.Parse(CurrentPrice.Text) * 100)).ToString() + "%";
我非常感谢尽可能详细的帮助将此方法转换为 MVVM 实现。如果相关,我的视图模型正在实现 MvvmHelpers 的 BaseViewModel。
非常感谢!
【问题讨论】:
我会为您的特殊格式和内容创建一个正面标签和另一个负面差异标签。然后,您可以将 IsVisible 属性绑定到 VM 中的某个属性,该属性决定它的价格是更高还是更低。 到底是什么问题?对我来说,这看起来像是“将其转换为 MVVM”编码请求。您是否尝试过创建属性、绑定它们、从另一个属性设置器更改/增加一个属性的通知等? 感谢 cmets。是的,我确实尝试过,但我是一个初学者,所以有很多问题,尤其是它是一个条目,我需要它的值和其他值。CurrentPrice.Text
是什么?它是一个常数吗? currentcost.text
也是常数吗?
【参考方案1】:
是的,您可以创建模型并为不同的控件创建不同的属性。
我根据您的代码创建了一个简单的演示(以PriceDifLabel
的文本和文本颜色为例)。
可以参考以下代码:
1.创建模型MyViewModel.cs
并实现接口INotifyPropertyChanged
。
而当我们改变UpdatedCost
的值时(bind for Entry UpdatedCost
),我们也可以相应地改变PriceDif
。
MyViewModel.cs
public class MyViewModel: INotifyPropertyChanged
double _updatedCost;
public double UpdatedCost
set
SetProperty(ref _updatedCost, value);
double diff = UpdatedCost - double.Parse(CurrentCost);
string sign = diff > 0 ? "+" : "";
PriceDif = "(" + sign + string.Format("0:0.0", diff) + ")";
PriceDifLabelColor = diff > 0 ? Color.Red : Color.Green;
System.Diagnostics.Debug.WriteLine("----------> PriceDif = " + PriceDif);
get return _updatedCost;
string _currentCost;
public string CurrentCost
set SetProperty(ref _currentCost, value);
get return _currentCost;
string _priceDif;
public string PriceDif
set SetProperty(ref _priceDif, value);
get return _priceDif;
Color _priceDifLabelColor = Color.Green;
public Color PriceDifLabelColor
set SetProperty(ref _priceDifLabelColor, value);
get return _priceDifLabelColor;
public MyViewModel()
CurrentCost = "2.5";
bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
if (Object.Equals(storage, value))
return false;
storage = value;
OnPropertyChanged(propertyName);
return true;
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
public event PropertyChangedEventHandler PropertyChanged;
2.在page.xaml
中绑定这些属性
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:testapp1="clr-namespace:TestApp1"
x:Class="TestApp1.TestPage2">
<ContentPage.BindingContext>
<testapp1:MyViewModel></testapp1:MyViewModel>
</ContentPage.BindingContext>
<ContentPage.Content>
<StackLayout>
<Entry x:Name="UpdatedCost" Text="Binding UpdatedCost" />
<Label x:Name="PriceDifLabel" Text=" Binding PriceDif" TextColor="Binding PriceDifLabelColor"/>
<Entry x:Name="CurrentCost" Text="2.5"/>
<Entry x:Name="CurPriceUpdatedCostProfit" Text="22%"/>
</StackLayout>
</ContentPage.Content>
</ContentPage>
更多关于INotifyPropertyChanged
接口,可以查看:
https://docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/data-binding/binding-mode#viewmodels-and-property-change-notifications.
【讨论】:
非常感谢您的详细解答!【参考方案2】:1.您好,您可以创建这个BaseViewModel,然后将其传递给每个ViewModel,那么您不必总是为每个ViewModel单独创建INotifyPropertyChanged接口。 然后你可以像这里一样将它继承到任何 ViewModel:
using YourApp.ViewModels
...
public class YourViewModel : BaseViewModel
....
//This is the BaseViewModel:
using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
using System.Runtime.CompilerServices;
namespace YourApp.ViewModel
public abstract class BaseViewModel : INotifyPropertyChanged
//declares the (required) PropertyChanged event that is defined by
//the interface.
public event PropertyChangedEventHandler PropertyChanged;
// next it is checked if someone has registered for the event,
// and in this case the event will be raised with the name of the
//property being updated.
protected void OnPropertyChanged([CallerMemberName] string
propertyName = "")
var changed = PropertyChanged;
if (changed == null)
return;
changed.Invoke(this, new
PropertyChangedEventArgs(propertyName));
// This is a helper method to make setting the property easier.
// Right now you can just take this with faith
// or if you are familiar with generics you can study it a little to
// see how it works.
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;
【讨论】:
以上是关于Xamarin 条目绑定到 MVVM的主要内容,如果未能解决你的问题,请参考以下文章
Xamarin.Forms 条目 - 自定义行为和 MVVM
Android--ListView与数据绑定(Xamarin)