INotifyPropertyChanged
[NotifyPropertyChanged] public class CustomerViewModel { public CustomerModel Customer { get; set; } public string FullName { get { // Change in Customer, Customer.FirstName or // Customer.PrincipalAddress.Line1 will trigger the event. return string.Format("{0} {1} from {2}", Customer?.FirstName, Customer?.LastName, Customer?.PrincipalAddress?.FullAddress); } } }
Get rid of 95% of the INotifyPropertyChanged boilerplate and never miss a notification again.
Support for composite properties and child objects
Consistent and reliable
Fully customizable
Integrates with other MVVM frameworks: MVVM Light and Caliburn.Micro
Command
[NotifyPropertyChanged] public partial class MainWindow : Window { bool isReadOnly; [Command] public ICommand SaveCommand { get; private set; } private void ExecuteSave() { // Details skipped. } public bool CanExecuteSave => !this.isReadOnly; }
Stop creating a class every time you define a command.
Easy, based on custom attributes and naming conventions.
Validated at build time.
CanExecute property integrates with the [NotifyPropertyChanged] aspect.
Dependency & Attached Properties
public partial class FancyTextBlock : UserControl { public FancyTextBlock() { InitializeComponent(); } [DependencyProperty] [Required] public string Text { get; set; } = "Hello, world."; [DependencyProperty] public Brush FancyBorderBrush { get; set; } public void OnFancyBorderBrushChanged() { /* Handle changes here. */} }
Dependency properties that still look like properties.
Support for composite properties and child objects.
Consistent and reliable.
Fully customizable.
Integrates with PostSharp code contracts.
Integrates with other MVVM frameworks.
Code Contracts
public interface IReferralService { [return: Required] Referral CreateReferral([Required] string name, [Url] string url); } public class ReferralService : IReferralService { public Referral CreateReferral(string name, string url) { // Contracts are automatically inherited from the interface. } [Required] public string ConnectionString { get; set; } }
The most readable way to validate values at run-time.
Works with parameters, output parameters, return values, fields, and properties.
Works on interfaces and abstract methods. Automatically inherited.
As fast as hand-written code.
Customizable and localizable exception messages.
Integrates with the [DependencyProperty] aspect.
Weak Event
static class MyEventSource { [WeakEvent] public static event EventHandler MyEvent; } class MyEventClient { public MyEventClient() { MyEventSource.MyEvent += (sender, e) => Console.WriteLine("Oops!"); // No need for IDisposable and handler unregistration. } }
Avoid the most common source of memory leaks in .NET.
As simple as a custom attribute.
Apply to all events in your project in a single line.
Undo/Redo
Give your users the familiar Undo/Redo experience without breaking the bank.
Undo/Redo any object state change.
Handle multiple changes as one step.
Expose in the UI with built-in or custom controls.
Tags: PostSharp, Development tool apps, .NET, PostSharp [MVVM]