Создание DataTemplate и DataTrigger в коде - PullRequest
4 голосов
/ 09 июня 2011

Я пытаюсь создать 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 #?

1 Ответ

6 голосов
/ 10 июня 2011

Name элементов является частным случаем (см. Примечания здесь , например).

Вы хотите оставить строку

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

И вместо этого установите FrameworkElementFactory.Name:

textFactory.Name = "element";

Это потому, что если свойство установлено после создания (что вы и сделали), оно больше не регистрируется таким же образом.

Один примечательный случай, когда настройка Name из кода важна, - это регистрация имен для элементов, с которыми будут работать раскадровки, чтобы на них можно было ссылаться во время выполнения. Прежде чем вы сможете зарегистрировать имя, может также потребоваться создать экземпляр и назначить экземпляр NameScope . См. Раздел «Пример» или Обзор раскадровок .

...