I have a custom control that has an ICommand dependency property. I would like to bind to this property from inside a DataTemplate. To make things clearer here’s my code:
DataForm class:
public class DataForm : Form
{
#region Properties
public ICommand HideForm
{
get { return (ICommand)GetValue(HideFormProperty); }
set { SetValue(HideFormProperty, value); }
}
public static readonly DependencyProperty HideFormProperty =
DependencyProperty.Register("HideForm", typeof(ICommand), typeof(DataForm), new PropertyMetadata(null));
#endregion
#region Ctors
public DataForm(Guid formId, String title)
: base(formId, title)
{
this.Template = Application.Current.Resources["DataFormDefaultTemplate"] as ControlTemplate;
}
public DataForm()
: this(Guid.NewGuid(), "bla")
{
}
#endregion
#region Methods
public override void OnApplyTemplate()
{
if (HeaderTemplate == null)
{
HeaderTemplate = Application.Current.Resources["DefaultFormHeaderTemplate"] as DataTemplate;
}
base.OnApplyTemplate();
}
#endregion
}
ControlTemplate of the DataForm:
<ControlTemplate x:Name="DataFormDefaultTemplate" TargetType="my:DataForm">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<ContentPresenter Grid.Row="0" ContentTemplate="{TemplateBinding HeaderTemplate}"></ContentPresenter>
<ContentPresenter Grid.Row="1" ContentTemplate="{TemplateBinding BodyTemplate}"></ContentPresenter>
<ContentPresenter Grid.Row="2" ContentTemplate="{TemplateBinding FooterTemplate}"></ContentPresenter>
</Grid>
</ControlTemplate>
The DataTemplate from which I want to bind to the HideForm command:
<DataTemplate x:Name="DefaultFormHeaderTemplate">
<Grid HorizontalAlignment="Stretch">
<my:TextField FieldViewStyle="{StaticResource formLabelStyle}" Value="Form Title" Mode="View"></my:TextField>
<my:ImageButtonField ImagePath="../Images/Popup_Close.png"
CommandToExecute="{Binding HideForm}"
HorizontalAlignment="Right" Width="8" Height="8"></my:ImageButtonField>
</Grid>
</DataTemplate>
Note: CommandToExecute does work properly on the ImageButtonField. I’ve already tested it.
Code to instantiate the DataForm:
DataForm form = new DataForm();
form.BodyTemplate = Application.Current.Resources["DataFormBodyTemplate"] as DataTemplate;
form.FooterTemplate = Application.Current.Resources["DataFormFooterTemplate"] as DataTemplate;
form.HideForm = new DelegateCommand(CloseIt);
How do I get this to work? Basically, the perfect scenario is to be able to bind to this command (and other properties) in the data template from the ViewModel without having to add that property (HideForm in this case) to the DataForm class. Shouldn’t the DataContext be inherited and – theoretically – what I’m saying should work?
Turned out that there is no way to get this done with a
DataTemplateunless you use a Binding Proxy. The other way around is to use aControlTemplateinstead and bind to theTemplateproperty of aContentControlinstead of using aContentPresenter