2011-06-09 80 views
4

我试图在代码隐藏中创建DataTemplate。我有一个DataTrigger在它的问题。在代码中创建DataTemplate和DataTrigger

这里的DataTemplate写在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> 
      </DataTrigger.EnterActions> 
     </DataTrigger> 
    </DataTemplate.Triggers> 
</DataTemplate> 

这里就是我写在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); 

一组该数据模板作为按钮的ContentTemplate。按钮是绑定到简单类的数据,这不是问题。

问题是,当我使用在代码中创建的数据模板,然后当Flag属性更改我得到以下异常 'element' name cannot be found in the name scope of 'System.Windows.DataTemplate'。虽然用xaml编写的模板完美地工作。

那么我在哪里失败翻译XAML到C#?

回答

7

元素的Name有点特殊情况(例如请参阅备注here)。

你要删除的行

textFactory.SetValue(TextBox.NameProperty, "element"); 

,并设置FrameworkElementFactory.Name代替:

textFactory.Name = "element"; 

这是因为如果该属性创建之后设置(这是你做了什么),它是没有以相同的方式注册更长时间。

从代码中设置名称很重要的一个值得注意的情况是,在为故事板运行的元素注册名称时,可以在运行时引用它们。在注册名称之前,可能还需要实例化并分配一个NameScope实例。请参阅示例部分或Storyboards Overview