Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add Click event in dynamical way

Tags:

c#

wpf

I am trying to add UI elements dynamically, but I am facing a problem, I able to add UI elements, but I fail to add click event to Button

Below is my code :

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);

And my onClick function :

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

For this line :

 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'>";

If I remove the

Click='btnMy_Click'

It will work. But if I add it, It shows

enter image description here

Anyone know how to solve this ? Thanks in advance.

like image 265
Anson Tan Avatar asked Jan 25 '26 08:01

Anson Tan


1 Answers

Since the error message states that to specify events, you need to compile your XAML file, and you specifically do not want to do that, it seems to be impractical (you may be able to compile a temporary assembly and load it, but then you can't unload it again).

What you could do is give the element a name:

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

And then, using a helper function to retrieve it:

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

The helper function looks like this, I took it from 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;
}
like image 98
Manuel Schweigert Avatar answered Jan 27 '26 22:01

Manuel Schweigert



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!