In my view I have this:
<TextBlock Text="{Binding Title}"/>
which binds to my ViewModel's Title property and this is straightforward and works well:
private string _title;
public string Title
{
get
{
return _title;
}
set
{
_title = value;
OnPropertyChanged("Title");
}
}
However my ViewModel also has the Property "FormFields" which is a StackPanel that contains a number of other UserControls:
private StackPanel _formFields;
public StackPanel FormFields
{
get
{
return _formFields;
}
set
{
_formFields = value;
OnPropertyChanged("FormFields");
}
}
How do I bind this from my view?
In ASP.NET there was a PlaceHolder element, I'm looking for something with the same functionality, e.g.
PSEUDO CODE:
<PlaceHolder Content="{Binding FormFields}"/>
Firstly, don't. Instead of dictating the UI from your VM, you should be dictating data (the model). In other words, the property type should be ObservableCollection<FormField>
. Then your view would bind as follows:
<ItemsControl ItemsSource="{Binding FormFields}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
This is generally defined in the .Resources
section of a parent element. I.e Window.Resources
or WrapPanel.Resources
.
Having said that, you can use a ContentPresenter
to grab the StackPanel
and stick it in the visual tree:
<ContentPresenter Content="{Binding FormFields}"/>
Have you tried using a Border
or just a plain Grid
?
<Border Content="{Binding FormFields}" />
Still, I'm questioning the design. The Form Fields should live in a view, and the view should be specified in data template which is instantiated based on the view model type. I wouldn't personally do what you're doing in code.
Cheers.