Binding to Complex Objects in the ViewModel from the View?
c#-4.0, complextype, data-binding, mvvm, wpf
Solution
Of course this is possible. However, WPF needs to know when any property along the path has changed. To that end, you need to implement `INotifyPropertyChanged` (or other supported mechanisms). In your example, both `Site` and the VM containing `SelectedSite` should implement change notification).
Here's how you could implement the functionality you specified in your question:
// simple DTO
public class Site
{
public string Name { get; set; }
public int SiteId { get; set; }
public bool IsLocal { get; set; }
}
// base class for view models
public abstract class ViewModel
{
// see http://kentb.blogspot.co.uk/2009/04/mvvm-infrastructure-viewmodel.html for an example
}
public class SiteViewModel : ViewModel
{
private readonly Site site;
public SiteViewModel(Site site)
{
this.site = site;
}
// this is what your view binds to
public string Name
{
get { return this.site.Name; }
set
{
if (this.site.Name != value)
{
this.site.Name = value;
this.OnPropertyChanged(() => this.Name);
}
}
}
// other properties
}
public class SitesViewModel : ViewModel
{
private readonly ICollection<SiteViewModel> sites;
private SiteViewModel selectedSite;
public SitesViewModel()
{
this.sites = ...;
}
public ICollection<SiteViewModel> Sites
{
get { return this.sites; }
}
public SiteViewModel SelectedSite
{
get { return this.selectedSite; }
set
{
if (this.selectedSite != value)
{
this.selectedSite = value;
this.OnPropertyChanged(() => this.SelectedSite);
}
}
}
}
And your view might look something like this (assuming a `DataContext` of type `SitesViewModel`):
<ListBox ItemsSource="{Binding Sites}" SelectedItem="{Binding SelectedSite}"/>
Problem
Say for example I have the following type: ``` public class Site { public string Name { get; set; } public int SiteId { get; set; } public bool IsLocal { get; set; } } ``` The above type can be assigned to be held in a Propety in a ViewModel like so assuming a corresponding backing field has been created but omitted here ofc: ``` public Site SelectedSite { get { return _selectedSite; } set { _selectedSite = value; // raise property changed etc } } ``` In my xaml a straight forward binding would be: ``` <TextBlock x:Name="StatusMessageTextBlock" Width="Auto" Height="Auto" Style="{StaticResource StatusMessageboxTextStyle}" Text="{Binding MessageToDisplay, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" /> ``` Can you extend a binding by using the dot notation syntax? e.g: ``` <TextBlock x:Name="StatusMessageTextBlock" Width="Auto" Height="Auto" Style="{StaticResource StatusMessageboxTextStyle}" **Text="{Binding SelectedSite.Name,** Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" /> ``` Seems like a an interesting feature but my gut instinct is a no as my DC is being assigned at RunTime so at DesignTime or CompileTime, I can't see any clues that could make this feature work or not? Correct me if have misunderstood what a complex object is, I have simplified mine down for the sake of this question.