none
Область видимости имен XAML RRS feed

  • Общие обсуждения

  • В Silverlight в области имен XAML хранятся связи между определенными в XAML именами объектов и их эквивалентами экземпляров. Это похоже на более широкое значение термина "область имен" в других языках и технологиях программирования. Области имен XAML создаются во время анализа источника XAML и создания объектного представления. Затем имена в области имен XAML используются операциями с выделенным кодом во время выполнения для доступа к объектам, которые были созданы в результате анализа XAML.

    Для более подробной информации читайте статью Область видимости имен XAML

    Помните следующие вещи при работе с областью имен:

    1. При создании нового объекта с помощью XamlReader.Load будет создана новая область имен.

      Частая проблема – это использование Storyboard для анимации динамически созданного объекта. Допустим имеется следующая разметка UserControl:

      <UserControl.Resources>
        <Storyboard x:Name="sb">
                <DoubleAnimation Storyboard.TargetName="btn" Storyboard.TargetProperty="Width" From="0" To="200"/>
           </Storyboard>
      </UserControl.Resources>
      

      В коде создается кнопка (Button), имеющая имя btn, с помощью XamlReader.Load:

      string xaml = @"<Button
        xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation""                     xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml""
       x:Name=""btn""/>";
      Button btn = (Button)XamlReader.Load(xaml);
      this.LayoutRoot.Children.Add(btn);
      this.sb.Begin();
      

      Выполнение данного кода приведет к вызову исключения, указывающее, что TargetName для Storyboadr(btn) не может быть найдет. Это происходит из-за того, что Storyboard находится в namescope1, а кнопка, созданная средствами XamlReader.Load – в namescope2. Storyboard не может ничего найти в namescope1 с именем btn.

      Один из путей решения данной проблемы заключается в удалении свойства TargetName в разметки анимации Storyboard, и установки этого свойства динамически в код, после создания кнопки. Пример:

      Storyboard.SetTarget(this.sb.Children[0], btn);
      Лучшим решение будет создание Storyboard для многократного использования разными элементами. Смотрите пункт – Как создать Storyboard и применить ее к нескольким элементам?

       

    2. Шаблоны (ControlTemplate и DataTemplate) определяют свою собственную область имен Распространенная проблема – из кода не удается найти элемент определенный в шаблоне. Например:

      <Button x:Name="btn" >
           <Button.Template>
                <ControlTemplate TargetType="Button">
                    <Rectangle x:Name="rect" Fill="Aqua"/>
                </ControlTemplate>
           </Button.Template>
      </Button>
      

      Попытка найти элемент Rectengle, имеющий имя rect, с помощью кода ниже, не приведет к успешному результату:

      Rectangle rect = (Rectangle)this.btn.FindName("rect"); // - не будет работать

      Для поиска Rectangle, можно подписаться на событие Loaded для него и там уже получить ссылку на объект, через параметр sender. Код ниже демонстрирует, как это сделать:

      private Rectangle rect;
      private void rect_Loaded(object sender, RoutedEventArgs e)
      {
           this.rect = (Rectangle)sender;
      }
      


    Для связи [mail]
    16 марта 2011 г. 13:02
    Модератор