views:

47

answers:

2

In C# (or in C# with WPF), how would I build a checkbox at run time? I would I be able to query the check box to see if the user clicked on it?

In other words, suppose I have a "grid" on which I want to have displayed some checkboxes. But I do not know how many checkboxes to display. I suppose I could (in WPF) fill the grid with checkboxes at design time and mark them as hidden (or visibly == false) and then show them at run time. But I was hoping there was a more elegant way to do this.

A: 

In an event handler or something like that, eventually a method that gets called, you could do this. Let's say your Canvas is called myCanvas.

var cb = new CheckBox { //... set the properties, e.g.:
                             Checked = true, Content = "Check me" };
// do whatever you like to do with your newly created CheckBox
myCanvas.Children.Add(cb);

Hope this helps; of course you can do this inside a loop. If you need to hold a specific set of references to the created CheckBoxes be aware of that or use the Tag Property to identify these special CheckBoxes. Also, you could check myCanvas.Children for CheckBoxes.

Andreas
+3  A: 

There are several ways to do this in WPF. A quick and dirty approach would be to do something like this:

<StackPanel x:Name="CheckBoxes" />

Then in your code behind do:

for (int i=0; i < 10; i++) {
    this.CheckBoxes.Children.Add(new CheckBox());
}

But while at first glance it looks simple, this makes it somewhat of a pain to work with in the long run. Instead, a better solution would be to have a class that has a boolean property such as:

// this should really implement INotifyPropertyChanged but
// we'll ignore that for now...
public class SelectableThing {

    public bool IsSelected {
        get;
        set;
    }

    public string Description {
        get;
        set;
    }

}

Then in your XAML, you would have a bindable control such as ItemsControl:

<ItemsControl x:Name="CheckBoxes">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <CheckBox IsChecked="{Binding IsSelected, Mode=TwoWay}"
                      Content="{Binding Description}" />
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

Then in your code behind you could create a collection of these SelectableThing's and set them as the ItemsSource.

private SelectableThing[] things;

// where you do this is up to you really
private void Window_Load(object sender, RoutedEventArgs e) {

    things = new SelectableThing[] {
        new SelectableThing("First Thing"),
        new SelectableThing("Second Thing"),
        new SelectableThing("Third Thing")
    };

    CheckBoxes.ItemsSource = things;

}
Josh Einstein
How would you control the location?
xarzu
In my example I used a StackPanel which arranges its children in a vertical "stack" by default. The Orientation property can be set to Horizontal. Using a layout panel like StackPanel instead of a Canvas will take the burden of manual positioning off of you. In WPF applications you should rarely have to position anything using X/Y coordinates.
Josh Einstein