Creating DataTemplate and DataTrigger in the code
I'm trying to create DataTemplate in code-behind. And I have a problem with DataTrigger in it.
Here is DataTemplate as written in xaml:
<DataTemplate x:Key="XamlTemplate" >
<TextBox Text="{Binding Name}" Name="element" Width="100"/>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Flag}" Value="true">
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="element" Storyboard.TargetProperty="Width"
To="200" Duration="0:0:2" />
</Storyboard>
</BeginStoryboard>
开发者_StackOverflow </DataTrigger.EnterActions>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
and here is what I've written in c#
var template = new DataTemplate();
//create visual tree
var textFactory = new FrameworkElementFactory(typeof(TextBox));
textFactory.SetBinding(TextBox.TextProperty, new Binding("Name"));
textFactory.SetValue(TextBox.NameProperty, "element");
textFactory.SetValue(TextBox.WidthProperty, 100D);
template.VisualTree = textFactory;
//create trigger
var animation = new DoubleAnimation();
animation.To = 200;
animation.Duration = TimeSpan.FromSeconds(2);
Storyboard.SetTargetProperty(animation, new PropertyPath("Width"));
Storyboard.SetTargetName(animation, "element");
var storyboard = new Storyboard();
storyboard.Children.Add(animation);
var action = new BeginStoryboard();
action.Storyboard = storyboard;
var trigger = new DataTrigger();
trigger.Binding = new Binding("Flag");
trigger.Value = true;
trigger.EnterActions.Add(action);
template.Triggers.Add(trigger);
A set this data template as ContentTemplate of a button. Button is data bound to simple class, that's not a problem.
The problem is that when I use data template created in code then when Flag
property changed I get the following exception
'element' name cannot be found in the name scope of 'System.Windows.DataTemplate'
. While template written in xaml works perfectly.
So where did I fail translating xaml into c#?
The Name
of elements is a bit of a special case (see remarks here for example).
You want to drop the line
textFactory.SetValue(TextBox.NameProperty, "element");
And set the FrameworkElementFactory.Name
instead:
textFactory.Name = "element";
This is because if the property is set after creation (which is what you did) it is no longer registered in the same way.
One notable case where setting Name from code is important is when registering names for elements that storyboards will run against, so that they can be referenced at run time. Before you can register a name, might also need to instantiate and assign a NameScope instance. See the Example section, or Storyboards Overview.
精彩评论