Skip to content

Creating WPF Elements In Code (VB or C#)

August 28, 2006

mrmckeb asked the following question on the WPF forum:

I am writing a program in which one object only appears if it a boolean value is true. The object is in the XAML code for the project. How can I make it so the object only ‘comes to life’/initializes under a certain circumstance?

Mike Greenway answered correctly with:

One way would be to leave it out of the .xaml then when the condition comes true, instansiate the item in the code behind.

 

I figured I’d show 3 different ways to instantiate elements using code behind:

  1. Toggling an elements visibility
  2. Creating the elements programmatically
  3. Programmatically getting a resource that was defined in XAML

and at the same time, I would highlight some small differences that VB & C# developers will see when working with Markup and Code.

 

Here is the small sample that has 2 buttons declared in XAML, but will create 2 buttons programmatically

 [Note-Thanks to Ian Griffiths, co-author of  Programming Windows Presentation Foundation to recommend we show the toggling of an elements visibility via a comment.]

RC1: Samples Require NetFx 3.0 RC1.

VB Sample :

Window1.xaml

<Window x:Class="Window1"
  xmlns="
http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  Title="ProgrammaticCreationOfElements in VB"
  SizeToContent="WidthAndHeight"
  FontSize="72"
  >
  <Window.Resources>
    <Button x:Key="maybe">Maybe</Button>
    <Style TargetType="{x:Type Button}">
      <Setter Property="Margin" Value="4" />
      <Setter Property="MinWidth" Value="1in" />

    </Style>
  </Window.Resources>
  <Grid Margin="10">
    <Grid.RowDefinitions>
      <RowDefinition Height="Auto" />
      <RowDefinition Height="Auto" />
    </Grid.RowDefinitions>
    <TextBlock>Choices:</TextBlock>
    <StackPanel Orientation="Horizontal" Name="container" Grid.Row="1">
      <Button>Ok</Button>
      <Button Name="cancelButton" Visibility="Hidden">Cancel</Button>
    </StackPanel>
  </Grid>
</Window>

 

Window1.xaml.vb

‘ Interaction logic for Window1.xaml
Partial Public Class Window1
  Inherits System.Windows.Window

  Public Sub New()
    InitializeComponent()
  End Sub

  Dim WithEvents perhapsButton As Button
  Dim WithEvents maybeButton As Button

  Public Sub Window1_Loaded(ByVal sender As Object, ByVal e As RoutedEventArgs) Handles Me.Loaded

    If (True) Then
      ‘Toggle the visibility of the Cancel Button
      cancelButton.Visibility = System.Windows.Visibility.Visible ‘VB IDE complained with Visibility.Visible

      ‘Create a button from scratch
      perhapsButton = New Button()
      perhapsButton.Content = "Perhaps"
      container.Children.Add(perhapsButton)

      ‘Create a button that was declared as a resource
      maybeButton = CType(Me.FindResource("maybe"), Button)
      container.Children.Add(maybeButton)
    End If
  End Sub

  Sub perhapsButton_Click(ByVal sender As Object, ByVal e As RoutedEventArgs) Handles perhapsButton.Click
    perhapsButton.Content = "or perhaps not"
  End Sub

  Sub maybe_click(ByVal sender As Object, ByVal e As RoutedEventArgs)
    maybeButton.Content = "or maybe not"
  End Sub
End Class

 

C# Sample:

Window1.xaml

<Window x:Class="ProgrammaticCreationOfElements.Window1"
  xmlns="
http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  Title="ProgrammaticCreationOfElements in C#"
  SizeToContent="WidthAndHeight"
  FontSize="72"
  Loaded="Window1_Loaded"
  >
  <Window.Resources>
    <Button x:Key="maybe" Click="maybe_click">Maybe</Button>
    <Style TargetType="{x:Type Button}">
      <Setter Property="Margin" Value="4" />
      <Setter Property="MinWidth" Value="1in" />
    </Style>
  </Window.Resources>
  <Grid Margin="10">
    <Grid.RowDefinitions>
      <RowDefinition Height="Auto" />
      <RowDefinition Height="Auto" />
    </Grid.RowDefinitions>
    <TextBlock>Choices:</TextBlock>
    <StackPanel Orientation="Horizontal" Name="container" Grid.Row="1">
      <Button>Ok</Button>
      <Button Name="cancelButton" Visibility="Hidden">Cancel</Button>
    </StackPanel>
  </Grid>
</Window>

Window1.xaml.cs

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace ProgrammaticCreationOfElements
{
  /// <summary>
  /// Interaction logic for Window1.xaml
  /// </summary>

  public partial class Window1 : System.Windows.Window
  {

    public Window1()
    {
      InitializeComponent();
    }

    void Window1_Loaded(object sender, RoutedEventArgs e)
    {

      if (true) //This would be where you could put your boolean logic.
      {

        //Toggle the visibility of the Cancel Button
        cancelButton.Visibility = Visibility.Visible;

         //Create a button from scratch
        Button perhapsButton = new Button();
        perhapsButton.Content = "Perhaps"
        perhapsButton.Click += new RoutedEventHandler(perhapsButton_Click);
        container.Children.Add(perhapsButton);

 

        //Create a button that was declared as a resource
        Button maybeButton = (Button)this.FindResource("maybe");
        container.Children.Add(maybeButton);
      }
    }

    void perhapsButton_Click(object sender, RoutedEventArgs e)
    {
      Button perhaps = (Button)sender;
      perhaps.Content = "or perhaps not"
    }

    void maybe_click(object sender, RoutedEventArgs e)
    {
      Button maybe = (Button)sender;
      maybe.Content = "or maybe not"
    } 
  }
}

 

Differences to hightlight for VB & C#:

  • x:Class in VB has an implied namespace already (the RootNamespace).
  • .vb files don’t usually have a namespace in them, they have an implied namespaces already (the RootNamespace property in the .vbproj)
  • Event wiring is traditionally done with a handles clause (and withevents) in the code behind of VB.

 

If you pay attention to those things, you’ll be able to adapt VB samples for C# use and C# samples for VB use.

From → WPF

10 Comments
  1. Ian permalink

    Wouldn\’t the Visibility property have been a simpler solution to this particular problem? The techniques you show are definitely useful, but I\’m wondering if I\’m missing something here about why you wouldn\’t just set the visibility of the relevant part to Collapsed.
     
    (Why the heck is it refusing to show my name on this comment? I\’m telling it to use my profile information, but it comes up with "(no name)" and no website… It\’s IanG here in case you were wondering. And also me on another bizarrely anonymous comment earlier on a different blog entry.)

  2. Brody permalink

    Brilliant!

  3. Rob permalink

    Ian-
    Yes, you are right, another technique is to have the markup in XAML, and just change the Visibility property – in fact it is the simplest way to do that.  I\’ll add that as a third technique to this sample.
     
    Perf wise, it is always better to only create when you need, but that would only show up with more substantial UI than the button example I am showing.
    Thanks, Rob

  4. Ahmad permalink

    I want to know how add element to grid at specific column and row.

  5. Unknown permalink

    How do you set the positioning of the button?I\’ve added controls on the fly:                Button button = new Button();                button.Content = "A New Button";                button.Height = 20;                button.Width = 50;I can set the height, and the width. but I have not found a way of setting the absolute position. If you could do this using System.Windows.Forms.Buttons, why not in System.Windows.Controls.Buttons?All the examples I have found have cunningly side-stepped illustrating this capability.Should I stick the control in a panel and let that take care of arranging things, or have I missed something blatantly obvious?Can I use button.SetValue()?

  6. Unknown permalink

    It was me who posted the query below, but I\’ve found a fix:This solution works on a Canvas (but not on a Grid for some reason):using System;using System.Collections.Generic;using System.Text;using System.Windows;using System.Windows.Controls;using System.Windows.Data;using System.Windows.Documents;using System.Windows.Input;using System.Windows.Media;using System.Windows.Media.Imaging;using System.Windows.Shapes;namespace WindowsApplication7{    /// <summary>    /// Interaction logic for Window1.xaml    /// </summary>    public partial class Window1 : System.Windows.Window    {        public Window1()        {            InitializeComponent();            Canvas c = (Canvas) FindName("c1");            if (c != null)            {                for (int x=0; x<5; x++)                {                    Button b = new Button();                    b.Content = "canvas" + Convert.ToString(x);                    b.Height = 30;                    b.Width = 120;                    Thickness m;                    m = (Thickness)b.GetValue(Button.MarginProperty);                    m.Top = (x * 30);                    m.Bottom = m.Top + b.Height;                    b.SetValue(CheckBox.MarginProperty, m);                    c.Children.Add(b);                }            }        }    }}

  7. Unknown permalink

    Sorry, didn\’t identify myself (see posts below).

  8. Unknown permalink

    (ZiggyShort)

  9. Unknown permalink

    Welcome to enter (wow gold) and (wow power leveling) trading site, (Rolex) are cheap, (World of Warcraft gold) credibility Very good! Quickly into the next single! Key words directly to the website click on transactions! -144748112789254

  10. Unknown permalink

    Amberdigital Branch,Southern Stars Enterprises Co is specializing in the development and manufacturing of screen advertisings, digital sign, digital signages and LCDs. Established in 1996, we have explored and developed the international market with professionalism. We have built a widespread marketing network, and set up a capable management team dedicated to provide beyond-expectation services to our customers.

    amberdigital Contact Us
    Southern Stars Enterprises Co (Hong Kong Office)
    Add:3 Fl, No.2, Lane 2, Kam Tsin Tsuen, Sheung Shui, Hong Kong
    Tel:+852 2681 4099
    Fax:+852 2681 4586
    Southern Stars Enterprises Co (Shenzhen Office)
    Add:DE, 16/F, Building 2, Nanguo Tower, Sungang Road, Shenzhen, China
    Tel:+86 755 2592 9100
    Fax:+86 755 2592 7171
    E-mail:sstar@netvigator.com
    website:www.amberdigital.com.hk
    alibaba:amberdigital.en.alibaba.com[aiehc

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: