2010-08-20 2 views
3

Я динамически строю свой файл данных с помощью XamlReader.Parse (string). Проблема в том, что я не могу помещать какие-либо события в какие-либо элементы управления, которые я создаю с помощью XamlReader. После нескольких исследований в Интернете я узнал, что это известное ограничение XamlReader.Использование событий/команд с XamlReader

Я не очень много знаю о командах в WPF, но могу ли я как-то использовать их для получения того же результата? Если да, то как? Если нет, я могу обработать событие в моем коде позади элемента управления, созданного с помощью Xaml Reader?

Ниже приведен пример создаваемого набора данных. У меня есть обработчик события MenuItem_Click, определенный в кодовом коде окна, который будет размещать этот файл данных.

При попытке запустить его возникла следующая ошибка: System.Windows.Markup.XamlParseException был необработанным: не удалось создать «Щелчок» из текста «MenuItem_Click».

DataTemplate result = null; 
     StringBuilder sb = new StringBuilder(); 

     sb.Append(@"<DataTemplate 
         xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation' 
         xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'> 
          <Grid Width=""Auto"" Height=""Auto""> 

          <TextBlock Text=""Hello""> 
           <TextBlock.ContextMenu> 
            <ContextMenu> 
             <MenuItem 
              Header=""World"" 
              Click=""MenuItem_Click""></MenuItem> 
            </ContextMenu> 
           </TextBlock.ContextMenu> 
          </TextBlock> 

          </Grid> 
         </DataTemplate>"); 

     result = XamlReader.Parse(sb.ToString()) as DataTemplate; 

ответ

0

Посмотрите на this link. Большинство решений там будут применяться и с Parse. Я не являюсь разработчиком C#, поэтому единственное, что я могу объяснить, - это последний вариант, который является чем-то вроде опции if-all-else-fail:

Сначала вы добавляете ID в свой XAML вместо Click и т. Д. Затем вы можете использовать FindLogicalNode, чтобы попасть в узлы, а затем подключить события самостоятельно.

Например, вы указываете свой MenuItem ID="WorldMenuItem". Затем в коде после вызова разбора, вы можете сделать это:

MenuItem worldMenuItem = (MenuItem)LogicalTreeHelper.FindLogicalNode(result, "WorldMenuItem"); 
worldMenuItem.Click += MenuItem_Click; // whatever your handler is 
+0

Возможно, я не могу получить этот фрагмент. FindLogicalNode принимает DependencyObject, поскольку это первый параметр, и я не могу понять, как отличать DataTemplate с DependencyObject. Есть идеи? –

+0

Я думаю, что я понял, как получить DependencyObject из DataTemplate ... Я использую DataTemplate.LoadContent(). Теперь проблема заключается в том, что независимо от того, что MenuItem никогда не обнаружено. Я знаю, что контекстное меню не входит в ту же VisualTree, что и остальные элементы управления, верно ли это для LogicalTree? –

5

Надеясь поздний ответ может помочь другим:

я обнаружил, что мне нужно связывать события после синтаксического анализа, и должен был удалите событие click из строки Xaml.

В моем сценарии я применил полученный DataTemplate к ItemTemplate, подключил ItemSource, а затем добавил обработчик. Это означает, что событие будет одинаковым для всех элементов, но в моем случае заголовок был необходимой информацией, а метод был тем же.

//Set the datatemplate to the result of the xaml parsing. 
myListView.ItemTemplate = (DataTemplate)result; 

//Add the itemtemplate first, otherwise there will be a visual child error 
myListView.ItemsSource = this.ItemsSource; 

//Attach click event. 
myListView.AddHandler(MenuItem.ClickEvent, new RoutedEventHandler(MenuItem_Click)); 

А потом событие щелчка нужно, чтобы вернуться к первоисточнику , отправитель будет ListView в моем случае, который с помощью DataTemplate.

internal void MenuItem_Click(object sender, RoutedEventArgs e){ 
    MenuItem mi = e.OriginalSource as MenuItem; 
    //At this point you can access the menuitem's header or other information as needed. 
}