Issue
I am trying to implement everything I can with MVVM rather than code behind, but if I have many objects that I need to access when the entry changes, I don't know how to do it well if at all.
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%"/>
Code-Behind:
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() + "%";
}
}
I would highly appreciate as detailed help as possible converting this method to MVVM implementation. If it is relevant, my view model is implementing BaseViewModel of MvvmHelpers.
Thank you very much!
Solution
Yes, you can create a model and create different properties for different controls.
I created a simple demo based on your code(take the PriceDifLabel
's text and text color for example).
You can refer to the following code:
1.create a model MyViewModel.cs
and implement interface INotifyPropertyChanged
.
And when we change the value of UpdatedCost
(bind for Entry UpdatedCost
),we can also change the PriceDif
accordingly.
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.bind these properties in 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>
For more about INotifyPropertyChanged
Interface, you can check:
Answered By - Jessie Zhang -MSFT
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.