1

I am c++ developer and from last week i started working on C# and WPF. I have a very simple query about using structures in my code. I have a label and button in my xaml class which should be dynamically generated. I had developed in c++ as follows:

typedef struct 
{
     String ChannelName;
     bool available;
} Voltage_Channel;

Voltage_Channel *m_voltageChannels;

Voltage_Channel redhookChannels[6] = {
  {"", false},
  {"VDD_IO_AUD", true},
  {"VDD_CODEC_AUD", true},
  {"VDD_DAL_AUD", true},
  {"VDD_DPD_AUD", true},
  {"VDD_PLL_AUD", true},    
};

m_voltageChannels = redhookChannels;

int cnt = 0; 
int MAX_ADC =6;

while(cnt < MAX_ADC)
{
    m_labelChannel[cnt] = new Label(m_voltageChannels[cnt].ChannelName); //Generates labels based on count
    m_setButton[cnt] = new TextButton("Set"); //generates Buttons based on Count
    m_setButton[cnt]->addButtonListener(this); // Event for the Button

    if(m_voltageChannels[cnt].available)
    {
        addAndMakeVisible(m_labelChannel[cnt]); //Displays if channel is available
        addAndMakeVisible(m_setButton[cnt]);
    }
}  

This generates the label and button 6 times and if channel is available then displays it.

I have the following in my Xaml File:

<Label Grid.Column="0" Content="{Binding VoltageLabel}" Name="VoltageLabel" />
<Button Grid.Column="1" Content="Set" Command="{Binding Path=SetButtonCommand}" Name="VoltageSetbtn" />

Label and Button Property:

string voltageLabel;
public string VoltageLabel
{
        get { return voltageLabel; }
        set
        {
            voltageLabel = value;
            OnPropertyChanged("VoltageLabel");
        }
}

    // Event for Set Button Click
    private ICommand mSetCommand;
    public ICommand SetButtonCommand
    {
        get
        {
            if (mSetCommand == null)
                mSetCommand = new DelegateCommand(new Action(SetCommandExecuted), new Func<bool>(SetCommandCanExecute));

            return mSetCommand;
        }
        set
        {
            mSetCommand = value;
        }
    }

    public bool SetCommandCanExecute()
    {
        return true;
    }

    public void SetCommandExecuted()
    {
        // Body of the method
    }

Is it possible to dynamically generate these controls using structures, looking at how I had done it in my C+ application???

Please help

StonedJesus
  • 397
  • 1
  • 5
  • 26

3 Answers3

1

All the controls available through declarative XAML-way can be added by code at runtime, too. So you can add them in a while/for/foreach loop to your view. All you need is the parent container.

A more elegant way would be to create a template within xaml and bind that template to the list containing the data.

A hint for auto-generated UI: Maybe it is an option to use the builtin PropertyGrid Control from M$ for your data (as seen in the Properties Window of Visual Studio). You can attach standard/custom editors for your data elements. There are also several "self-made" Property-Grids available, too.

Here is a link to a simple example how to use a template: http://wblum.org/listbind/net3/index.html

This question is also related to runtime control generation: Add WPF control at runtime

Community
  • 1
  • 1
Beachwalker
  • 7,685
  • 6
  • 52
  • 94
1

In C# controls are simple objects. Ultimately, every feature present in XAML can be coded. XAML is just a more convenient way to describe UI objects and the relations between them.

Each component has a children property that you can use to add sub elements. Adding a button to a form should work like this:

Button myButton= new Button();
form.Children.Add(myButton);
Samy Arous
  • 6,794
  • 13
  • 20
1

In WPF it is possible to directly map controls to be shown against objects, so for example I currently have,

<DataTemplate DataType="{x:Type ViewModel:Clock_t}">
     <View:Clock_tView/>
</DataTemplate>

and this will automatically wrap my Clock_t class with a ClockT_View in the UI.

However you tend to find that you need a some helpers for your View and you don't want to pollute your Model, so there is a pattern that says to introduce something in the middle, a ViewModel if you will. This pattern is called MVVM and is explained in Josh Smith's MVVM pattern article

To answer your question, yes you can do something like this

<ItemsControl ItemsSource="{Binding m_voltageChannels}"/>

and that will automatically try to display the VoltageChannel, but unless you have a DataTemplate you just get the result of its ToString() (usually the class name) six times. Instead either define a DataTemplate higher up in the resources somewhere, or just try

<ItemsControl ItemsSource="{Binding m_voltageChannels}">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Vertical">
                    <TextBlock Text="{Binding ChannelName}"/>
                    <CheckBox Content="Is available?" 
                         IsChecked="{Binding available}"/>
                </StackPanel>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
AlSki
  • 6,868
  • 1
  • 26
  • 39