Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. Creating and Binding UI objects in C# instead of XAML (WPF)

Creating and Binding UI objects in C# instead of XAML (WPF)

Scheduled Pinned Locked Moved C#
wpfcsharpwcfdesignxml
3 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    Member_14844540
    wrote on last edited by
    #1

    he application that I'm creating has a menu comprised of labels/headers. When you click on a menu item (a xaml Label) a drop down appears with subheaders related to that item. However, I need to make this menu customizable via XML. The idea is this, the XML outlines the header names as well as the subheader names for each menu item.

        NestedHeader1
        NestedHeader2
    
    
    
    
        NestedHeader1
        NestedHeader2
    

    I am able to read the XML using XDocument and bind a Dependency Property to the label context. The problem is that I do not know how many menu items might be in the XML file. I wanted to avoid creating a ton of labels and dependency properties for the label content to bind to. Instead of creating labels in xaml and binding to a property in C#, can I create UI items in C# and populate them with elements from a list at run time? There's some code below of how I'm getting and binding the data to a preexisting label.

    C#:

     public string HeaderName
     {
          get => (string)GetValue(HeaderNameProperty);
          set => SetValue(HeaderNameProperty, value);
     }
    
     public static readonly DependencyProperty HeaderNameProperty =
            DependencyProperty.Register("HeaderName", typeof(string), typeof(MainWindow));
    
     private void LoadHeaders()
    {
        var msg = new List(0);
        XDocument doc = null;
    
        try
        {
            doc = XDocument.Load("MenuHeaders.xml");
        }
        catch (Exception e)
        {
            msg.Add(string.Format("Unable to open file:{0}", ""));
            msg.Add(e.Message);
        }
    
        if(doc != null)
        {
            var allHeaders = doc.Descendants("Header").ToList();
            List headers = new List();
    
            foreach(XNode node in allHeaders)
            {
                XElement element = node as XElement;
                foreach(XAttribute attribute in element.Attributes())
                {
                    headers.Add(attribute.Value);
                }
            }
            HeaderName = headers\[0\];
        }
    }
    

    XAML:

    (As you may have n

    M Richard DeemingR 2 Replies Last reply
    0
    • M Member_14844540

      he application that I'm creating has a menu comprised of labels/headers. When you click on a menu item (a xaml Label) a drop down appears with subheaders related to that item. However, I need to make this menu customizable via XML. The idea is this, the XML outlines the header names as well as the subheader names for each menu item.

          NestedHeader1
          NestedHeader2
      
      
      
      
          NestedHeader1
          NestedHeader2
      

      I am able to read the XML using XDocument and bind a Dependency Property to the label context. The problem is that I do not know how many menu items might be in the XML file. I wanted to avoid creating a ton of labels and dependency properties for the label content to bind to. Instead of creating labels in xaml and binding to a property in C#, can I create UI items in C# and populate them with elements from a list at run time? There's some code below of how I'm getting and binding the data to a preexisting label.

      C#:

       public string HeaderName
       {
            get => (string)GetValue(HeaderNameProperty);
            set => SetValue(HeaderNameProperty, value);
       }
      
       public static readonly DependencyProperty HeaderNameProperty =
              DependencyProperty.Register("HeaderName", typeof(string), typeof(MainWindow));
      
       private void LoadHeaders()
      {
          var msg = new List(0);
          XDocument doc = null;
      
          try
          {
              doc = XDocument.Load("MenuHeaders.xml");
          }
          catch (Exception e)
          {
              msg.Add(string.Format("Unable to open file:{0}", ""));
              msg.Add(e.Message);
          }
      
          if(doc != null)
          {
              var allHeaders = doc.Descendants("Header").ToList();
              List headers = new List();
      
              foreach(XNode node in allHeaders)
              {
                  XElement element = node as XElement;
                  foreach(XAttribute attribute in element.Attributes())
                  {
                      headers.Add(attribute.Value);
                  }
              }
              HeaderName = headers\[0\];
          }
      }
      

      XAML:

      (As you may have n

      M Offline
      M Offline
      Mycroft Holmes
      wrote on last edited by
      #2

      You need to put a secondary loop into the Header loop to get the children of the header. How do you intend to bind the actions to the menu item?

      Never underestimate the power of human stupidity - RAH I'm old. I know stuff - JSOP

      1 Reply Last reply
      0
      • M Member_14844540

        he application that I'm creating has a menu comprised of labels/headers. When you click on a menu item (a xaml Label) a drop down appears with subheaders related to that item. However, I need to make this menu customizable via XML. The idea is this, the XML outlines the header names as well as the subheader names for each menu item.

            NestedHeader1
            NestedHeader2
        
        
        
        
            NestedHeader1
            NestedHeader2
        

        I am able to read the XML using XDocument and bind a Dependency Property to the label context. The problem is that I do not know how many menu items might be in the XML file. I wanted to avoid creating a ton of labels and dependency properties for the label content to bind to. Instead of creating labels in xaml and binding to a property in C#, can I create UI items in C# and populate them with elements from a list at run time? There's some code below of how I'm getting and binding the data to a preexisting label.

        C#:

         public string HeaderName
         {
              get => (string)GetValue(HeaderNameProperty);
              set => SetValue(HeaderNameProperty, value);
         }
        
         public static readonly DependencyProperty HeaderNameProperty =
                DependencyProperty.Register("HeaderName", typeof(string), typeof(MainWindow));
        
         private void LoadHeaders()
        {
            var msg = new List(0);
            XDocument doc = null;
        
            try
            {
                doc = XDocument.Load("MenuHeaders.xml");
            }
            catch (Exception e)
            {
                msg.Add(string.Format("Unable to open file:{0}", ""));
                msg.Add(e.Message);
            }
        
            if(doc != null)
            {
                var allHeaders = doc.Descendants("Header").ToList();
                List headers = new List();
        
                foreach(XNode node in allHeaders)
                {
                    XElement element = node as XElement;
                    foreach(XAttribute attribute in element.Attributes())
                    {
                        headers.Add(attribute.Value);
                    }
                }
                HeaderName = headers\[0\];
            }
        }
        

        XAML:

        (As you may have n

        Richard DeemingR Offline
        Richard DeemingR Offline
        Richard Deeming
        wrote on last edited by
        #3

        The XMLDataProvider might be a simpler option: How to: Bind to XML Data Using an XMLDataProvider and XPath Queries - WPF | Microsoft Docs[^] If you want to stick with code, you're going to need a class to represent the menu item. For example:

        public class MenuHeaderItem
        {
        public string HeaderName { get; set; }
        public IReadOnlyList<MenuHeaderItem> Children { get; set; }
        }

        public static IReadOnlyList<MenuHeaderItem> LoadMenu(XDocument document)
        {
        var result = new List<MenuHeaderItem>();
        var allHeaders = document.Descendants("Header");
        foreach (XElement node in allHeaders)
        {
        result.Add(new MenuHeaderItem
        {
        HeaderName = (string)node.Attribute("Value"),
        Children = node.Elements().Select(el => new MenuHeaderItem
        {
        HeaderName = (string)el,
        }).ToList(),
        });
        }

        return result;
        

        }

        Bind the loaded values to a read-only dependency property:

        private static readonly DependencyPropertyKey MenuHeadersKey = DependencyProperty.RegisterReadOnly(
        "MenuHeaders",
        typeof(IReadOnlyList<MenuHeaderItem>),
        typeof(YourContainingClass),
        new PropertyMetadata(null)
        );

        public static readonly DependencyProperty MenuHeadersProperty = MenuHeadersKey.DependencyProperty;

        public IReadOnlyList<MenuHeaderItem> MenuHeaders
        {
        get { return (IReadOnlyList<MenuHeaderItem>)GetValue(MenuHeadersProperty); }
        private set { SetValue(MenuHeadersKey, value); }
        }

        private void LoadHeaders()
        {
        if (File.Exists("MenuHeaders.xml"))
        {
        XDocument document = XDocument.Load("MenuHeaders.xml");
        MenuHeaders = LoadMenu(document);
        }
        }

        Then bind the MenuHeaders collection to your menu.

        <Menu ItemsSource="{Binding Path=MenuHeaders}">
        <Menu.ItemContainerStyle>
        <Style TargetType="{x:Type MenuItem}">
        <Setter Property="Header" Value="{Binding Path=HeaderName}" />
        <Setter Property="ItemsSource" Value="{Binding Path=Children}" />

        "These people looked deep within my soul and assigned me a number based on the order in which I joined" - Homer

        1 Reply Last reply
        0
        Reply
        • Reply as topic
        Log in to reply
        • Oldest to Newest
        • Newest to Oldest
        • Most Votes


        • Login

        • Don't have an account? Register

        • Login or register to search.
        • First post
          Last post
        0
        • Categories
        • Recent
        • Tags
        • Popular
        • World
        • Users
        • Groups