2016-05-31 1 views
3

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

Ниже мой код:

ParserContext context = new ParserContext(); 
context.XmlnsDictionary.Add("", "http://schemas.microsoft.com/winfx/2006/xaml/presentation"); 
context.XmlnsDictionary.Add("x", "http://schemas.microsoft.com/winfx/2006/xaml"); 

string xaml = String.Format(" <StackPanel Orientation='Vertical'>"); 
xaml = xaml + "<StackPanel Orientation='Horizontal'>"; 
xaml = xaml + "<Button Margin='5,5,0,0' Background='AliceBlue' Foreground='DarkBlue' Height='25' VerticalAlignment='Bottom' HorizontalAlignment='Right' Width='82' Tag='12' Click='btnMy_Click'>"; 
xaml = xaml + "<StackPanel Orientation='Horizontal'>"; 
xaml = xaml + "<Image Source='/MotionTest;component/images/open.png' Width='18' Height='18' />"; 
xaml = xaml + "<TextBlock Text=' Open' VerticalAlignment='Center' FontSize='13' />"; 
xaml = xaml + "</StackPanel>"; 
xaml = xaml + "</Button>"; 
xaml = xaml + "</StackPanel>"; 
xaml = xaml + "</StackPanel>"; 

UIElement element = (UIElement)XamlReader.Parse(xaml, context); 
myTestGrid.Children.Add(element); 

И моя OnClick функция:

private void btnMy_Click(object sender, RoutedEventArgs e) 
{ 
    var myValue = ((Button)sender).Tag; 
    MessageBox.Show("Here = " + myValue); 
} 

Для этой линии:

xaml = xaml + "<Button Margin='5,5,0,0' Background='AliceBlue' Foreground='DarkBlue' Height='25' VerticalAlignment='Bottom' HorizontalAlignment='Right' Width='82' Tag='12' Click='btnMy_Click'>"; 

Если удалить

Click='btnMy_Click' 

Он будет работать. Но если я добавить его, он показывает

enter image description here

Кто знает, как решить эту проблему? Спасибо заранее.

+0

Как об этом [Динамические обработчики событий для Xaml только] (https://denisvuyka.wordpress.com/2010/02/21/dynamic-event-handlers-for-xaml-only-silverlight-content-xamlreader-ramora-pattern-and-mef /) –

+2

Похож, что 'XamlReader.Parse' не поддерживает обработчики событий. Если бы это было так, то, по крайней мере, понадобился бы какой-то контекст, чтобы иметь возможность разрешать методы обработчика событий. Есть ли какая-то особая причина, по которой вам нужно разбирать XAML во время выполнения, вместо использования шаблонов данных или просто переключать видимость элементов пользовательского интерфейса? –

+0

Дорогой Питер, мой прикладной интерфейс динамичен, он не фиксирован. –

ответ

3

Поскольку в сообщении об ошибке указано, что для указания событий необходимо скомпилировать ваш файл XAML, и вы специально не хотите этого делать, это кажется непрактичным (вы можете скомпилировать временную сборку и загрузить ее , но потом вы не можете его разгрузить).

Что вы можете сделать, это дать элементу имя:

xaml = xaml + "<Button x:Name='ClickMe'>"; 

И затем, используя вспомогательную функцию для его получения:

var button = UIHelper.FindChild<Button>(element, "ClickMe"); 
button.Click += btnMy_Click; 

Вспомогательная функция выглядит так, я взял его от How can I find WPF controls by name or type?:

/// <summary> 
/// Finds a Child of a given item in the visual tree. 
/// </summary> 
/// <param name="parent">A direct parent of the queried item.</param> 
/// <typeparam name="T">The type of the queried item.</typeparam> 
/// <param name="childName">x:Name or Name of child. </param> 
/// <returns>The first parent item that matches the submitted type parameter. 
/// If not matching item can be found, 
/// a null parent is being returned.</returns> 
public static T FindChild<T>(DependencyObject parent, string childName) 
    where T : DependencyObject 
{  
    // Confirm parent and childName are valid. 
    if (parent == null) return null; 

    T foundChild = null; 

    int childrenCount = VisualTreeHelper.GetChildrenCount(parent); 
    for (int i = 0; i < childrenCount; i++) 
    { 
    var child = VisualTreeHelper.GetChild(parent, i); 
    // If the child is not of the request child type child 
    T childType = child as T; 
    if (childType == null) 
    { 
     // recursively drill down the tree 
     foundChild = FindChild<T>(child, childName); 

     // If the child is found, break so we do not overwrite the found child. 
     if (foundChild != null) break; 
    } 
    else if (!string.IsNullOrEmpty(childName)) 
    { 
     var frameworkElement = child as FrameworkElement; 
     // If the child's name is set for search 
     if (frameworkElement != null && frameworkElement.Name == childName) 
     { 
     // if the child's name is of the request name 
     foundChild = (T)child; 
     break; 
     } 
    } 
    else 
    { 
     // child element found. 
     foundChild = (T)child; 
     break; 
    } 
    } 

    return foundChild; 
} 
+0

Спасибо, это работает. –

Смежные вопросы