WPF MVVM View with lookup or join to other entities - wpf

I am getting started with WPF and MVVM. I am just reading up on Code Project Article which is quite interesting and provides a good quick start. I am using Entity Framework and I am happy I have listed all of my entities in a ListView.
I am curious how you would correctly implement lookups - in the view model or create a new model. Take the simple case of a person. The data structure might be:
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime DateOfBirth { get; set; }
public Toy FaveToy { get; set; }
}
public class Toy
{
public string Name { get; set; }
public string Model { get; set; }
public string Manufacturer { get; set; }
}
I want my list view to show the columns FirstName, LastName, DateOfBirth, Fave Toy, Manufacturer.
The Toy field will be a combined string with Name + " " + Model in.
So given some of the code in the example I've linked (I've knocked the Person class up for examples sake):
Base Class for the views
public abstract class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
My implementation for the Person view
public class PersonViewModel : ViewModelBase
{
private ObservableCollection<Person> _Person;
public PersonViewModel()
{
_Person = new ObservableCollection<Person>();
Entities context = new Entities();
foreach(var person in context.Person.ToList())
{
_Person.Add(person);
}
}
public ObservableCollection<Person> Person
{
get
{
return _Person;
}
set
{
_Person = value;
this.OnPropertyChanged("Person");
}
}
}

If I am understanding correct you want to access a Toy through the FaveToy property automatically.
Normally this would be done creating a relation between Person and Toy. Once you've done so your Person entity type would look like this:
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime DateOfBirth { get; set; }
public virtual Toy FaveToy { get; set; }
}
Notice the "virtual" on FaveToy. This indicates a navigation property which would be accessible through person instance.FaveToy. This can be represented in XAML either through dot notation or using the path property on your binding. Here is a link that discusses navigation properties: http://msdn.microsoft.com/en-us/data/jj713564.aspx
If you want to represent the toy by a combination of name and model then a converter would do the trick on the binding. Here is a link that discusses converters http://msdn.microsoft.com/en-us/library/system.windows.data.ivalueconverter.aspx
Hope this helps...Jason
PS - Josh Smith is awesome in his discussion of WPF and MVVM http://joshsmithonwpf.wordpress.com/a-guided-tour-of-wpf/
If you're a VB guy Alessandro has trhe best discussion for VB that I've seen: http://community.visual-basic.it/Alessandroenglish/archive/2010/08/13/31861.aspx
PSS -- WPF and MVVM (or Windows 8 and XAML) are awesome. Definitely worth your time to pick up.

Related

Raising OnPropertyChanged in the setter of each property vs Instance of Object

Information for the question:
I am trying to understand how to properly implement INotifyPropertyChanged on objects and collections.
First, here is my ViewModelBase class:
public abstract class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertychanged([CallerMemberName] string propertyName = "")
{
var handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
Consider that I have a class called Person:
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
public string Age { get; set; }
}
To use INotifyPropertyChanged, most examples that I have seen change the Person class to something like this:
public class Person
{
public int Id { get; set; }
private string _name;
public string Name
{
get { return _name; }
set
{
_name = value;
OnPropertychanged();
}
}
private string _age;
public string Age
{
get { return _age; }
set
{
_age = value;
OnPropertychanged();
}
}
}
It seems to work exactly the same when used a single time on an instance of the object (This might be useful if there are a lot of properties):
private Person _person;
public Person MyPerson
{
get { return _person; }
set
{
_person = value;
OnPropertychanged();
}
}
Actual question:
1 - Does it make a difference (aside from amounts of code) whether you call OnPropertychanged() on each individual property verses on an instance of an object? (Are both considered good practice?)
2 - If setting OnPropertychanged() on the object instance is good practice, am I correct to create an ObservableCollection like this?:
var PersonCollection = new ObservableCollection<MyPerson>();
1) Well, if you want to call it on object instance, then you need to do it every time you use your class like this in binding. When you implement OnNotifyPropertyChanged directly inside your class, you don't need to care about it later on...
2) Classes with INotifyPropertyChanged do not require Observable collections. This is however must when you are binding colection do some UI control (ListBox, ListView) and want to add/remove its elements. Observable collection will then make sure the UI gets updated.
The ObservableCollections object... When adding and removing from this collection the UI will be notified of the changes (Top Level). If you have an "ObservableCollection of Person" and you change a property on the one of the objects(Person) in the list the UI will not update unless your "Person" class implements the INotifyPropertyChanged interface, which can be put into a base class that all classes can inherit from like your example. I hope this helps a little.

Which one is a better data design or object model?

Overview
I am designing a mechanism for generating dynamic controls in an ASP.NET MVC application that uses ADO.NET Entity Framework. However, my question has nothing to do with MVC and a little to do with the Entity Framework. It is about comparing two object models.
Problem Statement
In my app, a user must have the ability to interact with Web page A to specify that he wants to add such and such HTML controls to Web Page B.
When he browses Web Page B next, he must see those controls and be able to use them.
What Is Not The Challenge
I have written the code to generate the controls. That was the easy part. I used the Tag Builder, Partial Views, HtmlHelper extensions and Display & Editor templates.
The Challenge
The challenge is in arriving at a database design and an object model generated by Entity Framework to hold the metadata about the controls that need to be generated.
I have come up with a database design as shown below:
You may ignore the User and Permissions tables. They are not relevant to our discussion.
Entity Framework generates the following entities based on the above database design.
Let's call my database design as Design Option A.
I would have wanted a design that looked more like this:
Let's call this second design as Design Option B.
The code (stripped down version) for this second option would look like this:
namespace DynamicControls
{
public class DynamicControlGroup
{
public long Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public string Controller { get; set; }
public IEnumerable<string> Actions { get; set; }
public DateTime StartDate { get; set; }
public DateTime? EndDate { get; set; }
public User CreatedByUser { get; set; }
public DateTime CreationDateTime { get; set; }
public User LastModifiedBy { get; set; }
public DateTime ModificationDateTime { get; set; }
// Navigational
public ICollection<DynamicControl<T>> DynamicControls { get; set; }
}
public class DynamicControl<T>
{
public long Id { get; set; } //db Id
public string HtmlId { get; set; }
public bool ValueRequired { get; set; }
public virtual ControlType ControlType { get; protected set; }
// Every control is capable of having a default value but of a different
// type. Most controls have default values of type text (string). The
// multi-select ones (checkboxes, multi-select lists, etc.) have a default
// value of type IEnumerable<string>. So, I want to leave this generic.
// But I am not that hung-up on this. I am fine if I am required to move
// this property DefaultValue from the base class and make it a concrete
// (not generic) property for each individual child class.
// Mostly I just want the heirarchy. And before that, I want to know
// if it is a good idea to model this heirarchy. Or is it better to just
// work with what my Entity Framework produced for my db?
// Should I change my db? I can because I thought-up the design for
// those tables.
public virtual T DefaultValue { get; set; }
// Navigational
public DynamicControlGroup DynamicControlGroup { get; set; }
}
public class TextBox : DynamicControl<string>
{
public override ControlType ControlType
{
get
{
return DynamicControls.ControlType.TextBox;
}
}
public string Label { get; set; }
public int MaxLength { get; set; }
}
public class PasswordControl : TextBox
{
public override ControlType ControlType
{
get
{
return DynamicControls.ControlType.Password;
}
}
}
public class TextArea : TextBox
{
public override ControlType ControlType
{
get
{
return DynamicControls.ControlType.TextArea;
}
}
public int Rows { get; set; }
}
public class DropDownList: DynamicControl<string>
{
public override ControlType ControlType
{
get
{
return ControlType.DropDownList;
}
}
// I want something like this. That I should be able to say
//
// myDropDownListObject.Options...
//
// You'll notice that given my current database design, I have
// no direct way of accessing the options of a, say, drop down list.
// To do that, I have to make a round-about Linq query.
public ICollection<DynamicControlOption> Options { get; set; }
}
public class DynamicControlOption
{
public long Id { get; set; } // db Id
public string OptionHtmlId { get; set; }
public string OptionValue { get; set; }
public string OptionText { get; set; }
// Navigational property
public DynamicControl<IEnumerable<string>> TheControlWhoseOptionIAm { get; set; }
}
public class User
{
}
public class Permission
{
}
public enum ControlType
{
TextBox,
TextArea,
Password,
RadioButton,
Checkbox,
DropDownList,
MultiSelectList,
DatePicker,
TimePicker,
DateTimePicker
}
}
My Question
1) I feel that I'd like Design Option B better. Am I feeling right?
2) I know I can work with Design Option A just as fine but it'll involve a little round-about way to do some things. For example, to get all the options for a drop down list, there's not navigational property on the DropDownList class in Design Option A. I'll have to write a round-about Linq query to do that.
3) Is it possible to have Entity Framework come close to generating Design Option B? How? What changes will I need to make to my database design to achieve that?
Now we are working on a Project like this at our company...
If I got your meaning correctly and If I were you...I implemented inherited structure as my database design like below.
Now you Classes are inheritance but your database design is not.
I have removed Id in TextBox and I have put ControlId as PK and FK in the same time. (not just FK).
in fact,ControlId is both PK for TextBox and FK from DynamicControl
and also this way for PasswordControl and TextArea
and Now ControlId in TextBox is not Identity. It gets it's ControlId from DynamicControl
I also accept Design Option B .I'm always more comfortable than using Design Option A.in my idea It's true and main structure

How to return hierarchical graph with RIA services

I would like a DomainService as follows:
[EnableClientAccess]
public class FamilyService : DomainService
{
public IQueryable<Person> GetPeople() // for the time being fake out a set of people
{
var people = new[]{ new Person(), ... };
return people.AsQueryable();
}
}
The Person class should be simple enough:
public class Person
{
[Key]
public Guid Id { get; set; }
public Person Parent { get; set; }
public String Name { get; set; }
public Person[] Children { get; set; }
}
In the Silverlight client, the Person class that is generated does not include the Parent or Children properties. What am I missing?
(Perhaps I should point out that while this is obviously a mock example, I am planning on using a loosely coupled approach, that this mimics. In fact most of my data doesn't reside in a database at all A significant majority of the RIA samples use an end-to-end parity of model from the database to the UI, which is not an option in my case.)
Try adding the [Include] attribute to the Parent & Children properties.
public class Person
{
[Key]
public Guid Id { get; set; }
[Include]
public Person Parent { get; set; }
public String Name { get; set; }
[Include]
public Person[] Children { get; set; }
}
If the Person class is coming out of the DB (in your real world app) and you are using EF, then you need to force them to be loaded eagerly, using the .Include() method.

Castle Windsor proxies, implicit interfaces and WPF Binding

I am attempting to implement a WPF ViewModel using Castle Windsor Dynamic Proxies. The idea is that I want to supply an interface (IPerson below should suffice as an example), a concrete backing class, and an interceptor (for providing automatic implementation of INotifyPropertyChanged). The interceptor implementation is here: http://www.hightech.ir/SeeSharp/Best-Implementation-Of-INotifyPropertyChange-Ever
The problem that I am seeing is that when I bind my models to WPF controls, the controls don't see the models as implementing INotifyPropertyChanged. I believe (but am not sure) that this is because Windsor is implementing the interfaces explicitly, and WPF seems to expect them to be implicit.
Is there any way to make this work, so that changes to the model are caught by the interceptor and raised to the model?
All versions of the libraries are the latest: Castle.Core 2.5.1.0 and Windsor 2.5.1.0
Code is as follows:
// My model's interface
public interface IPerson : INotifyPropertyChanged
{
string First { get; set; }
string LastName { get; set; }
DateTime Birthdate { get; set; }
}
// My concrete class:
[Interceptor(typeof(NotifyPropertyChangedInterceptor))]
class Person : IPerson
{
public event PropertyChangedEventHandler PropertyChanged = (s,e)=> { };
public string First { get; set; }
public string LastName { get; set; }
public DateTime Birthdate { get; set; }
}
// My windsor installer
public class Installer : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(
Component.For<NotifyPropertyChangedInterceptor>()
.ImplementedBy<NotifyPropertyChangedInterceptor>()
.LifeStyle.Transient);
container.Register(
Component.For<IPerson, INotifyPropertyChanged>()
.ImplementedBy<Person>().LifeStyle.Transient);
}
}
So the answer turned out to be fairly straightforward... The code from http://www.hightech.ir/SeeSharp/Best-Implementation-Of-INotifyPropertyChange-Ever defines the interceptor as:
public class NotifyPropertyChangedInterceptor : IInterceptor
{
private PropertyChangedEventHandler _subscribers = delegate { };
public void Intercept(IInvocation invocation)
{
if (invocation.Method.DeclaringType == typeof(INotifyPropertyChanged))
{
HandleSubscription(invocation);
return;
}
invocation.Proceed();
if (invocation.Method.Name.StartsWith("set_"))
{
FireNotificationChanged(invocation);
}
}
private void HandleSubscription(IInvocation invocation)
{
var handler = (PropertyChangedEventHandler)invocation.Arguments[0];
if (invocation.Method.Name.StartsWith("add_"))
{
_subscribers += handler;
}
else
{
_subscribers -= handler;
}
}
private void FireNotificationChanged(IInvocation invocation)
{
var propertyName = invocation.Method.Name.Substring(4);
_subscribers(invocation.InvocationTarget, new PropertyChangedEventArgs(propertyName));
}
}
In my case, the InvocationTarget was simply not the right entity to be passing as the first argument to PropertyChanged (because I am generating a proxy). Changing the last function to the following fixed the problem:
private void FireNotificationChanged(IInvocation invocation)
{
var propertyName = invocation.Method.Name.Substring(4);
_subscribers(invocation.Proxy, new PropertyChangedEventArgs(propertyName));
}
I think you need to make the members of your Class that implements the interface Virtual.

Modeling a Generic Relationship (expressed in C#) in a Database

This is most likely one for all you sexy DBAs out there:
How would I effieciently model a relational database whereby I have a field in an "Event" table which defines a "SportType"?
This "SportsType" field can hold a link to different sports tables E.g. "FootballEvent", "RubgyEvent", "CricketEvent" and "F1 Event".
Each of these Sports tables have different fields specific to that sport.
My goal is to be able to genericly add sports types in the future as required, yet hold sport specific event data (fields) as part of my Event Entity.
Is it possible to use an ORM such as NHibernate / Entity framework / DataObjects.NET which would reflect such a relationship?
I have thrown together a quick C# example to express my intent at a higher level:
public class Event<T> where T : new()
{
public T Fields { get; set; }
public Event()
{
EventType = new T();
}
}
public class FootballEvent
{
public Team CompetitorA { get; set; }
public Team CompetitorB { get; set; }
}
public class TennisEvent
{
public Player CompetitorA { get; set; }
public Player CompetitorB { get; set; }
}
public class F1RacingEvent
{
public List<Player> Drivers { get; set; }
public List<Team> Teams { get; set; }
}
public class Team
{
public IEnumerable<Player> Squad { get; set; }
}
public class Player
{
public string Name { get; set; }
public DateTime DOB { get; set;}
}
DataObjects.Net supports automatic mappings for open generics. Some details on this are described here.
You can do this by having all the Event types inherit from an abstract Event base class. This make sense to me because all the events share some common properties: date, venue, etc. You can use a table per concrete class or table per subclass strategy to store the objects in a relational database. Here are some links to articles describing inheritance mapping with NHibernate:
Chapter 8. Inheritance Mapping
Fluent NHibernate and Inheritance Mapping
NHibernate Mapping – Inheritance
The example converted to DO4 must look as follows:
// I'd add this type - adding an abstract base makes design more clean + allows you to share
// the behavior among all the descendants
[Serializable]
[HierarchyRoot]
public abstract class EventBase : Entity
{
[Key]
Guid Id { get; private set; } // Or some other type
}
[Serializable]
public class Event<T> : EventBase
where T : IEntity, new() // IEntity indicates DO4 must try to map its descendants automatically
// Although I'd put some stronger requirement, e.g. by using IEventData instead of IEntity here
{
public T Data { get; set; }
public Event(T data)
{
Data = data;
}
}
[Serializable]
[HierarchyRoot]
public class FootballEvent
{
// You need [Key] here
public Team CompetitorA { get; set; }
public Team CompetitorB { get; set; }
}
[Serializable]
[HierarchyRoot]
public class TennisEvent
{
// You need [Key] here
public Player CompetitorA { get; set; }
public Player CompetitorB { get; set; }
}
[Serializable]
[HierarchyRoot]
public class F1RacingEvent
{
// You need [Key] here
public EntitySet<Player> Drivers { get; private set; }
public EntitySet<Team> Teams { get; private set; }
}
[Serializable]
[HierarchyRoot]
public class Team
{
// You need [Key] here
public EntitySet<Player> Squad { get; set; }
}
[Serializable]
[HierarchyRoot]
public class Player
{
public string Name { get; set; }
public DateTime DOB { get; set; }
}
In this case Event instances will be available (= mapped automatically) for all suitable Ts from model. E.g. in this case they'll be:
- EventBase // Yes, even it, coz it's suitable
- FootballEvent
- TennisEvent
- F1RacingEvent
- Team
- Player
If you'd like to restrict this to just certain types, you must do the following:
- Add an interface inherited from IEntity all these types will support, e.g. IEventData.
- Use it as generic parameter constraint for generic parameter T in Event.
Cross Posted from: http://forum.x-tensive.com/viewtopic.php?f=29&t=5820,
Answer By Alex Yakunin,
Chief Executive DataObjects.NET
There are a bunch of options like XML columns and EAV (also known as database within a database), but none of which will translate well with an ORM to traditional static object-oriented languages, and all of which have drawbacks with respect to data type safety and referential integrity at the database level.
If you need this level of dynamic structure in both the database and the client, you might need to go with an object or document database (and language) which is much more dynamic by design - relational databases tend to work best with static relationships and data models.

Resources