views:

71

answers:

1

Adding an x:Name attribute to a XAML element normally results in a member variable being added to the backing class that can then be accessed using normal code. When the element in question is part of the DataTemplate, the field does not get created.

I can sort of understand that the DataTemplate is making this a special case but can anyone explain the underlying principle to me? Also what are the options for getting access to the object within .NET Code?

<dataControls:DataForm x:Name="CompanyDetail" CurrentItem="{Binding CurrentItem}" AutoGenerateFields="False">
    <dataControls:DataForm.EditTemplate>
        <DataTemplate>
            <StackPanel dataControls:DataField.IsFieldGroup="True">
                <dataControls:DataField Label="About">
                    <Border Height="150" Style="{StaticResource HtmlPlaceHolderBorderStyle}" Width="298" VerticalAlignment="Top">
                        <telerik:RadHtmlPlaceholder x:Name="uxAboutHtml" x:FieldModifier="Public" HtmlSource="{Binding About, Mode=TwoWay}"/>
                    </Border>
                </dataControls:DataField>
            </StackPanel>
        </DataTemplate>
    </dataControls:DataForm.EditTemplate>
</dataControls:DataForm>
A: 

You can use the FrameworkElement.FindName("objectName") method on the parent of the DataTemplate e.g. var uxAboutHtml = CompanyDetail.FindName("uxAboutHtml"); to get a reference to the object. The downside to this is that paramater passed to FindName does not end up being strongly typed with the XAML x:Name"objectName" attribute.

I have changed tack on this and am now referencing the underlying object that the control is being bound to, which is probably a better way to go.

var htmlContent = (CompanyViewModel)CompanyDetail.CurrentItem;
Martin Hollingsworth
Did you actually test the FindName approach, I've not been able to reproduce a successful test for it and according to my understanding (which could be wrong however) it shouldn't work?
AnthonyWJones
You could be right. In my test I was using the DataForm.FindNameInContentMethod. Using reflector I see that this method actually accesses this._contentPresenter.Content.FindName provided _contentPresenter is not set. I also searched and found that you should only use FindName once the Template has been applied. The http://msdn.microsoft.com/en-us/library/system.windows.frameworkelement.findname%28VS.95%29.aspx documentation discusses this.
Martin Hollingsworth