Xaml design time data: Radical.Design similar values
- design time data introduction;
- setup a basic design time environment;
- lively change values at design time;
- using dynamic properties to live change other properties;
where the address view model is:class PersonViewModel : INotifyPropertyChanged { public ObservableCollection<AddressViewModel> Addresses { get; private set; } //remaining code omitted for clarity }
And finally this is the UI we want to design with design time data:class AddressViewModel : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged = ( s, e ) => { }; private void OnPropertyChanged( string propertyName ) { var h = this.PropertyChanged; h( this, new PropertyChangedEventArgs( propertyName ) ); } String _street; public String Street { get { return _street; } set { _street = value; this.OnPropertyChanged( "Street" ); } } String _city; public String City { get { return _city; } set { _city = value; this.OnPropertyChanged( "City" ); } } }
where obviously we want to see a list of addresses.
First of all we need to declare to the designer that we want to expose the new property, in the constructor add the following snippet:
this.Expose( vm => vm.Addresses );
The property is immediately available at design time to be bound to the ItemsSource property of the ListView:And in the same manner we can design ListView columns:
But we want more we want to see a list of addresses with values, but now we have to face an interesting type safety problem.
Statically typing
In order to keep things safe everything in Radical.Design aims to be type safe in fact if you try to set a value the the Addresses exposed property you get the intellisense ask for a ObservableCollection<AddressViewModel>:
That is an interesting sitcom :-) we have type safety where basically we do not need it, the designer is totally non-interested in the types, in term of type safety, it is interested in the shape of the types we are passing along.
Enter “similarity”
Since we, as developers, are confortable with type safety in a scenario like the one outlined above we can ask Radical.Design to trust us:
we are telling to the infrastructure: use a list of DesignTimeAddressViewModel and trust me they will be structurally equivalent (from a designer point of view) to a observable collection of AddressViewModel and since we have defined the new design time view model in this way:this.Expose( vm => vm.Addresses ) .WithSimilarValue( new List<DesignTimeAddressViewModel>() { new DesignTimeAddressViewModel() } );
As soon as we select columns in the ListView designer we get what we expect:public class DesignTimeAddressViewModel : DesignTimeHost<AddressViewModel> { public DesignTimeAddressViewModel() { this.Expose( vm => vm.City ) .WithStaticValue( "Milan" ); this.Expose( vm => vm.Street ) .WithStaticValue( "Piazza Duomo" ); } }
But we want even more, we want to let the UI guys to edit the addresses list directly in the designer.
.m