111,092
社区成员




<Application x:Class="MvvmTutorial.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
</Application>
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
var shell = new ShellView();
shell.Show();
}
using MvvmTutorial.Infrastructure;
namespace MvvmTutorial.Models
{
/// <summary>
/// Our Contact model, which stores data retrieved from data persistence layer
/// </summary>
public class Contact : ObservableObject
{
#region Fields
string _name;
string _phoneNumber;
#endregion // Fields
#region Properties
public string Name
{
get
{
return _name;
}
set
{
if (_name != value)
{
_name = value;
RaisePropertyChanged(() => Name);
}
}
}
public string PhoneNumber
{
get
{
return _phoneNumber;
}
set
{
if (_phoneNumber != value)
{
_phoneNumber = value;
RaisePropertyChanged(() => PhoneNumber);
}
}
}
#endregion // Properties
}
}
using System;
using System.ComponentModel;
using System.Linq.Expressions;
namespace MvvmTutorial.Infrastructure
{
public class ObservableObject : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public virtual void RaisePropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
public void RaisePropertyChanged<T>(Expression<Func<T>> propertyExpression)
{
var propertyName = PropertySupport.ExtractPropertyName(propertyExpression);
this.RaisePropertyChanged(propertyName);
}
}
}
using System;
using System.Linq.Expressions;
using System.Reflection;
namespace MvvmTutorial.Infrastructure
{
public static class PropertySupport
{
public static string ExtractPropertyName<T>(Expression<Func<T>> propertyExpression)
{
if (propertyExpression == null)
{
throw new ArgumentNullException("propertyExpression");
}
var memberExpression = propertyExpression.Body as MemberExpression;
if (memberExpression == null)
{
throw new ArgumentException("The expression is not a member access expression.", "propertyExpression");
}
var property = memberExpression.Member as PropertyInfo;
if (property == null)
{
throw new ArgumentException("The member access expression does not access a property.", "propertyExpression");
}
var getMethod = property.GetGetMethod(true);
if (getMethod.IsStatic)
{
throw new ArgumentException("The referenced property is a static property.", "propertyExpression");
}
return memberExpression.Member.Name;
}
}
}
using System.Collections.Generic;
using System.Collections.ObjectModel;
using MvvmTutorial.Infrastructure;
using MvvmTutorial.Models;
namespace MvvmTutorial.ViewModels
{
public class ContactMasterViewModel : ObservableObject
{
#region Fields
private bool _isLoaded;
private ObservableCollection<Contact> _items = new ObservableCollection<Contact>();
#endregion // Fields
#region Properties
public IEnumerable<Contact> Items
{
get
{
// If we load this view model in design mode (for example, in VS or Expression),
// we add some random data so that we can preview the layout of our view
if (DesignHelper.IsInDesignMode)
{
for (int i = 0; i < 25; ++i)
{
_items.Add(new Contact().GenerateRandomData());
}
}
else if (!_isLoaded)
{
Load();
}
return _items;
}
}
#endregion // Properties
#region Private Methods
private void Load()
{
// TODO: Once we finish the implementation of data persistence layer,
// we need to re-write this code to make this method work for real-world app.
// We haven't implemented data persistence
// Therefore, we temporarily load some random data in memory
for (int i = 0; i < 25; ++i)
{
_items.Add(new Contact().GenerateRandomData());
}
_isLoaded = true;
}
#endregion // Private Methods
}
}
public class A:INotifyPropertyChanged
{
public B b{get;set;}
}
public class B:INotifyPropertyChanged
{
public int c{get;set;}
}
这个时候我实例化对象A,而发生改变的是对象B中的属性c,按照道理说,引发的应该是c这个属性,对于A来说是捕获不到的,那么如果要A能捕获到c这个属性的变化,需要在A类中将这个INotifyPropertyChanged冒泡处理吧,是不是引发属性名为"b.c"这样的写法呢?对于这样的多级处理有点含糊。