Note that there are some explanatory texts on larger screens.

plurals
  1. POIs there some event showing that new ContentTemplate is completely applied?
    text
    copied!<p>I have a ContentControl that I want to change it's ContentTemplate in some event. I want to add some values (text to TextBox) when control in ContentTemplate loaded. But, I has discovered that new ContentTemplate is applied (in terms of loading all controls of new template) NOT DIRECTLY after changing property ContentTemplate.</p> <pre><code>myContentControl.ContentTemplate = newContentTemplate; // at this line controls of new template are not loaded! </code></pre> <p>I tested by added this code after that line:</p> <pre><code>var cp = GetVisualChild&lt;ContentPresenter&gt;(myContentControl); var txt = myContentControl.ContentTemplate.FindName("Path_Cover", cp) as TextBox; txt.Text = "test"; </code></pre> <p>GetVisualChild</p> <pre><code>private T GetVisualChild&lt;T&gt;(DependencyObject parent) where T : Visual { T child = default(T); int numVisuals = VisualTreeHelper.GetChildrenCount(parent); for (int i = 0; i &lt; numVisuals; i++) { Visual v = (Visual)VisualTreeHelper.GetChild(parent, i); child = v as T; if (child == null) { child = GetVisualChild&lt;T&gt;(v); } if (child != null) { break; } } return child; } </code></pre> <p>I've got an error:</p> <blockquote> <p>This operation is valid only on elements that have this template applied.</p> </blockquote> <p>Is there some event showing that new ContentTemplate is completely applied?</p> <p><strong>EDIT 1</strong></p> <p>@eran I tried onApplyTemplate</p> <pre><code>public override void OnApplyTemplate() { var cp = GetVisualChild&lt;ContentPresenter&gt;(Content_Option); var txt = Content_Option.ContentTemplate.FindName("Path_Cover", cp) as TextBox; txt.Text = "test"; } </code></pre> <p>but got error:</p> <blockquote> <p>Object reference not set to an instance of an object.</p> </blockquote> <p><strong>EDIT 2</strong></p> <p>this "dirty" method works just fine:</p> <pre><code>myContentControl.ContentTemplate = newContentTemplate; System.Windows.Threading.DispatcherTimer timer = new System.Windows.Threading.DispatcherTimer(); timer.Interval = TimeSpan.FromMilliseconds(0.000001); timer.Tick += new EventHandler(delegate(object s, EventArgs a) { timer.Stop(); var cp = GetVisualChild&lt;ContentPresenter&gt;(Content_Option); var txt = Content_Option.ContentTemplate.FindName("Path_Cover", cp) as TextBox; txt.Text = "teSt"; }); timer.Start(); </code></pre> <p>can somebody help me to achieve the same result with more "clean" (profesional) way :)</p> <p><strong>EDIT 3</strong></p> <p>My Scenario is, I have a TreeView (on left side) as menu and a Grid (on right side) as display for ContentControl. TreeView has some nodes. Each node has it's own DataTemplate. Each time a TreeView node clicked, a DataTemplate is set to ContentControl and a value (ex. Path_Cover.Text) is set from database. The layout more or less like windows explorer.</p> <p>Well, this is all necessary code:</p> <p><strong>XAML</strong></p> <pre><code> &lt;UserControl.Resources&gt; &lt;DataTemplate x:Key="General"&gt; &lt;StackPanel&gt; &lt;DockPanel&gt; &lt;TextBlock Text="Cover"/&gt; &lt;TextBox Name="Path_Cover"/&gt; &lt;/DockPanel&gt; &lt;DockPanel&gt; &lt;TextBlock Text="Slide"/&gt; &lt;TextBox Name="Path_Slide"/&gt; &lt;/DockPanel&gt; &lt;/StackPanel&gt; &lt;/DataTemplate&gt; &lt;DataTemplate x:Key="Appearance"&gt; &lt;StackPanel&gt; &lt;DockPanel&gt; &lt;TextBlock Text="Cover"/&gt; &lt;TextBox Name="Path_Cover"/&gt; &lt;/DockPanel&gt; &lt;DockPanel&gt; &lt;Button Content="Get Theme"/&gt; &lt;TextBox Name="Txt_Theme"/&gt; &lt;/DockPanel&gt; &lt;/StackPanel&gt; &lt;/DataTemplate&gt; &lt;UserControl.REsources&gt; &lt;Grid&gt; &lt;ContentControl Name="myContentControl"/&gt; &lt;/Grid&gt; </code></pre> <p><strong>Code Behind</strong></p> <pre><code>private void TreeMenu_SelectionChanged(object sender, SelectionChangedEventArgs e) { myContentControl.ContentTemplate =(DataTemplate)this.Resources[Tree_Menu.SelectedItem.ToString()]; System.Windows.Threading.DispatcherTimer timer = new System.Windows.Threading.DispatcherTimer(); timer.Interval = TimeSpan.FromMilliseconds(0.000001); timer.Tick += new EventHandler(delegate(object s, EventArgs a) { timer.Stop(); switch (Tree_Menu.SelectedItem.ToString()) { case "General": var cp = GetVisualChild&lt;ContentPresenter&gt;(Content_Option); var txt = Content_Option.ContentTemplate.FindName("Path_Cover", cp) as TextBox; txt.Text = "test"; txt = Content_Option.ContentTemplate.FindName("Path_Slide", cp) as TextBox; txt.Text = "test"; break; case "Appearance": var cp = GetVisualChild&lt;ContentPresenter&gt;(Content_Option); var txt = Content_Option.ContentTemplate.FindName("Txt_Theme", cp) as TextBox; txt.Text = "test"; break; } }); timer.Start(); } </code></pre> <p>I'm just need to "move" the code inside timer.tick event handler to some new event that fire after DataTemplate/ContentTemplate completely applied.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload