Is there some event showing that new ContentTemplate is completely applied? Is there some event showing that new ContentTemplate is completely applied? wpf wpf

Is there some event showing that new ContentTemplate is completely applied?


I'm aware this is quite an old question but I've been looking for an answer to this and having invented one, thought this would be a good place to share it.

I have simply created my own ContentPresenter class extending from the standard ContentPresenter:

public class ContentPresenter : System.Windows.Controls.ContentPresenter {    #region RE: ContentChanged    public static RoutedEvent ContentChangedEvent = EventManager.RegisterRoutedEvent("ContentChanged", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(ContentPresenter));    public event RoutedEventHandler ContentChanged {        add { AddHandler(ContentChangedEvent, value); }        remove { RemoveHandler(ContentChangedEvent, value); }    }    public static void AddContentChangedHandler(UIElement el, RoutedEventHandler handler) {        el.AddHandler(ContentChangedEvent, handler);    }    public static void RemoveContentChangedHandler(UIElement el, RoutedEventHandler handler) {        el.RemoveHandler(ContentChangedEvent, handler);    }    #endregion    protected override void OnVisualChildrenChanged(System.Windows.DependencyObject visualAdded, System.Windows.DependencyObject visualRemoved) {        base.OnVisualChildrenChanged(visualAdded, visualRemoved);        RaiseEvent(new RoutedEventArgs(ContentChangedEvent, this));    }}

I hope this may help those of you out there looking for a simple solution to this glaring oversight in the design of ContentPresenter.


In general I do not know any events of that kind. But a typical WPF way for your scenario is this:

<ContentControl Name=myContentControl><ContentControl.ContentTemplate>    <DataTemplate>        <StackPanel>            ...other controls here            <TextBox Text={Binding Mode=TwoWay}/>            ... more controls here        </StackPanel>    </DataTemplate></ContentControl.ContentTemplate>

Code behind:

myContentControl.Content = "Test";

Or you can bind the Content to (propperty of) a ViewModel and put the code in there.

If you want to get to a control inside the contenttemplate, you just give it a name and perform a FindName from the control to which the contenttemplate is applied. There is no need for that searching for a contentpresenter with that VisualChild stuff.

I have a feeling you are mixing up controltemplates and datatemplates (contenttemplate, itemtemplate).

  1. OnApplyTemplate refers to the moment the ControlTemplate is applied, so not the ContentTemplate or any other datatemplate.
  2. ContentPresenters are a typical ingredient of ControlTemplates and not ContentTemplates.


I don't think there is such event in WPF framework. You can however assure that your code is run after the newly assigned content template is applied.

The way to accomplish this (and a "proper" version of your "dirty" solution) is to utilize the Dispatcher associated with your ContentControl. This code will do just what you're trying to achieve:

myContentControl.ContentTemplate = newContentTemplate;myContentControl.Dispatcher.BeginInvoke(DispatcherPriority.Loaded, new Action(() =>{    var cp = GetVisualChild<ContentPresenter>(myContentControl);    var txt = myContentControl.ContentTemplate.FindName("Path_Cover", cp) as TextBox;    txt.Text = "test";}));

Notice that the priority with which this code will be executed is set to DispatcherPriority.Loaded, so it will be executed with the same priority as the code you put in the FrameworkElement.Loaded event handler.