मेरे पास एक ContentControl है जिसे मैं किसी ईवेंट में इसकी सामग्री टेम्पलेट को बदलना चाहता हूं। सामग्री टेम्पलेट में नियंत्रण करते समय मैं कुछ मान (टेक्स्टबॉक्स पर टेक्स्ट) जोड़ना चाहता हूं। लेकिन, मैंने पाया है कि नया ContentTemplate लागू किया गया है (नए टेम्पलेट के सभी नियंत्रण लोड करने के मामले में) संपत्ति ContentTemplate बदलने के बाद सीधे नहीं।क्या कोई घटना दिखा रही है कि नया ContentTemplate पूरी तरह से लागू है?
var cp = GetVisualChild<ContentPresenter>(myContentControl);
var txt = myContentControl.ContentTemplate.FindName("Path_Cover", cp) as TextBox;
txt.Text = "test";
GetVisualChild
private T GetVisualChild<T>(DependencyObject parent) where T : Visual
{
T child = default(T);
int numVisuals = VisualTreeHelper.GetChildrenCount(parent);
for (int i = 0; i < numVisuals; i++)
{
Visual v = (Visual)VisualTreeHelper.GetChild(parent, i);
child = v as T;
if (child == null)
{
child = GetVisualChild<T>(v);
}
if (child != null)
{
break;
}
}
return child;
}
मैं एक त्रुटि मिल गया है:
myContentControl.ContentTemplate = newContentTemplate;
// at this line controls of new template are not loaded!
मुझे लगता है कि लाइन के बाद इस कोड को जोड़ा द्वारा परीक्षण
This operation is valid only on elements that have this template applied.
वहाँ कुछ घटना है यह नया सामग्री टेम्पलेट दिखा रहा है ई पूरी तरह से लागू है?
संपादित करें 1
@eran मैं onApplyTemplate
public override void OnApplyTemplate()
{
var cp = GetVisualChild<ContentPresenter>(Content_Option);
var txt = Content_Option.ContentTemplate.FindName("Path_Cover", cp) as TextBox;
txt.Text = "test";
}
कोशिश की, लेकिन मिला त्रुटि:
Object reference not set to an instance of an object.
संपादित 2
इस "गंदे" विधि बस ठीक काम करता है:
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<ContentPresenter>(Content_Option);
var txt = Content_Option.ContentTemplate.FindName("Path_Cover", cp) as TextBox;
txt.Text = "teSt";
});
timer.Start();
किसी ने मुझसे मदद कर सकते हैं और अधिक "क्लीन" (profesional) जिस तरह से :)
संपादित के साथ एक ही परिणाम प्राप्त करने के 3
मेरे परिदृश्य है, मेरे पास ContentControl के लिए डिस्प्ले के रूप में मेनू और एक ग्रिड (दाईं तरफ) के रूप में एक TreeView (बाईं तरफ) है। ट्री व्यू में कुछ नोड्स हैं। प्रत्येक नोड का अपना डेटा टेम्पलेट होता है। प्रत्येक बार जब TreeView नोड क्लिक किया जाता है, तो DataTemplate ContentControl पर सेट होता है और एक मान (उदा। पथ_Cover.Text) डेटाबेस से सेट होता है। लेआउट अधिक या कम विंडोज एक्सप्लोरर की तरह।
XAML
<UserControl.Resources>
<DataTemplate x:Key="General">
<StackPanel>
<DockPanel>
<TextBlock Text="Cover"/>
<TextBox Name="Path_Cover"/>
</DockPanel>
<DockPanel>
<TextBlock Text="Slide"/>
<TextBox Name="Path_Slide"/>
</DockPanel>
</StackPanel>
</DataTemplate>
<DataTemplate x:Key="Appearance">
<StackPanel>
<DockPanel>
<TextBlock Text="Cover"/>
<TextBox Name="Path_Cover"/>
</DockPanel>
<DockPanel>
<Button Content="Get Theme"/>
<TextBox Name="Txt_Theme"/>
</DockPanel>
</StackPanel>
</DataTemplate>
<UserControl.REsources>
<Grid>
<ContentControl Name="myContentControl"/>
</Grid>
पीछे
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<ContentPresenter>(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<ContentPresenter>(Content_Option);
var txt = Content_Option.ContentTemplate.FindName("Txt_Theme", cp) as TextBox;
txt.Text = "test";
break;
}
});
timer.Start();
}
कोड मैं कर रहा हूँ बस "चाल" टाइमर के अंदर कोड की जरूरत है:
खैर, यह सभी आवश्यक कोड है कुछ घटनाओं के लिए टिक इवेंट हैंडलर जो डेटा टेम्पलेट/कंटेंट टेम्पलेट के बाद पूरी तरह से लागू होता है।
ऑनलोड या ऑनलोड लोड को ऑनएपप्ले टेम्पलेट के बाद कॉल किया गया है msdn –
@eran ऑनलोड ईवेंट केवल एक बार आग लगती है। मैं ऐसी घटना चाहता हूं जो हर बार सामग्री टेम्पलेट को बदलता है। – Reyn