MVVM - How to keep formatted properties up to date?

I am working on a Windows Phone application that uses MVVM, but I am struggling with the implementation of MVVM for properties that need to be formatted from the model class for display in the view.

Let's say that I have a simple model class called Person.

public class Person {

   public string Name { get; set; }
   public DateTime Birthday { get; set; }

}

There is a list of objects Personthat are loaded from a locally saved file, and I want to show the list of persons on the list page, and then allow the user to click on a person to go to the details page, where there is more detailed information about this person.

On the list page, I want to show the person’s birthday as "Birthday: 2/22/1980" (where "2/22/1980" is a person, formatted Birthday)

On the details page I want to show a person’s birthday in a different format: "Eric birthday is 2/22/1980" (where "Eric" is a person Nameand "2/22/1980" a person is formatted Birthday).

Usually I just create a view model that formats correctly Birthday:

public class PersonViewModel {

   private Person person;

   public PersonViewModel(Person person) {
      this.person = person;
   }

   public string BirthdayForList {
      get {
         return "Birthday: " + person.Birthday.ToString("ddd", CultureInfo.CurrentCulture);
      }
   }

   public string BirthdayForDetails {
      get {
         return person.Name + " birthday is " + person.Birthday.ToString("ddd", CultureInfo.CurrentCulture);
      }
   }

}

To show these values ​​in the user interface, I would create a collection of these view model objects (and bind them to the view):

ObservableCollection<PersonViewModel> Items

Now, what should I do when the person’s birthday is updated (somewhere on the details page) and make sure that it is Itemsupdated with updated properties BirthdayForListand BirthdayForDetails, at the same time, save Personlocally?

, Person, PersonViewModel , .

? ObservableCollection PersonViewModel? , -, NotifyPropertyChanged.

(: . , Birthday , , - .)

+4
6

xaml " "?

<TextBlock>
    <TextBlock.Text>
        <MultiBinding StringFormat="{}{0} birthday is {1:ddd}">
            <Binding Path="Person.Name">
            <Binding Path="Person.BirthDay">
        </MultiBinding>
    </TextBlock.Text>
</TextBlock>

, , INotifyPropertyChanged Person .

EDIT: , MVVM light, ViewModel ObservableObject INotifyPropertyChanged

public string FirstName
{
    get { return _firstName; }
    set
    {
        _firstName = value;
        RaisePropertyChanged(() => FirstName);
    }
}
private string _firstName;
+5

XAML , , ViewModel. , INotifyPropertyChanged PropertyChanged , - .

- ... , MVVM framework Catwalk, ViewModel. ,

  public string BirthdayForDetails
  {
    get
    {
      return Calculated(() => this.Name + " birthday is " + this.Birthday.ToString("ddd", CultureInfo.CurrentCulture));
    }
  }

PropertyChanged BirthdayForDetails, . ObservableModel, Birthday Name ,

  public string Name
  {
    get { return GetValue<string>(); }
    set { SetValue(value); }
  }

, , .

+2

:

  • XAML. .

  • .

, , . /. , , - .

0

PersonViewModels ObservableCollection , , PersonViewModel / .

, , , . , , .

, , , . , ViewModel INotifyPropertyChanged DependencyObject ( : INotifyPropertyChanged DependencyProperty ViewModel).

INotifyPropertyChanged. PropertyChanged. , . , , ViewModel, .

(, ) OnPropertyChanged .

public class PersonViewModel : INotifyPropertyChanged
{
    private Person person;

    public PersonViewModel(Person person)
    {
        this.person = person;
    }

    public DateTime Birthday
    {
        get { return person.Birthday; }
        set 
        { 
            person.Birthday = value;
            OnPropertyChanged("Birthday");
            OnPropertyChanged("BirthdayForList");
            OnPropertyChanged("BirthdayForDetails");
        }
    }

    public string Name
    {
        get { return person.Name; }
        set 
        { 
            person.Name = value; 
            OnPropertyChanged("Name");
            OnPropertyChanged("BirthdayForDetails");
        }
    }

    public string BirthdayForList
    {
        get
        {
            return "Birthday: " + Birthday.ToString("ddd", CultureInfo.CurrentCulture);
        }
    }

    public string BirthdayForDetails
    {
        get
        {
            return Name + " birthday is " + Birthday.ToString("ddd", CultureInfo.CurrentCulture);
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}

, . , , , OnPropertyChanged , .

, ViewModel ( ) .

, - / . googeling "INotifyPropertyChanged " . ( INotifyPropertyChanged ), .

MVVM Framework, .

, .

0

You can simply call the PropertyChanged method in the customizer of your "person" property

like this

private Person myPerson;
public Person MyPerson
{
    get { return myPerson; }
    set
    {
        myPerson = value;
        PropertyChanged("MyPerson");
        PropertyChanged("BirthdayForList");
        PropertyChanged("BirthdayForDetails");
    }
}
0
source

You can use a combination of several elements embedded inside a TextBlock element

<TextBlock Foreground="DarkGray" VerticalAlignment="Bottom" Margin="0,0,0,8"><Run Text="total length "/><Run Text="{Binding TotalHours}" FontSize="48"/><Run Text="h "/><Run Text=":" FontSize="48"/><Run Text="{Binding TotalMinutes}" FontSize="48"/><Run Text="m "/></TextBlock>

Somewhat like this sample fooobar.com/questions/169024 / ...

0
source

All Articles