使用C#中的结构数组动态生成UI组件

时间:2012-10-11 11:21:42

标签: c# c++ .net wpf dynamic

我是c ++开发人员,上周我开始研究C#和WPF。我有一个关于在我的代码中使用结构的非常简单的查询。我的xaml类中有一个标签和按钮,应该动态生成。我用c ++开发了如下:

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

这会生成标签和按钮6次,如果频道可用,则显示它。

我的 Xaml 文件中包含以下内容:

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

标签和按钮属性:

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
    }

是否可以使用结构动态生成这些控件,看看我是如何在我的C +应用程序中完成的?

请帮忙

3 个答案:

答案 0 :(得分:1)

通过声明式XAML方式提供的所有控件也可以在运行时通过代码添加。因此,您可以将while / for / foreach循环添加到视图中。您只需要父容器。

更优雅的方法是在xaml中创建模板并将该模板绑定到包含数据的列表。

自动生成的UI的提示: 也许可以选择使用M $内置的PropertyGrid控件来获取数据(如Visual Studio的“属性”窗口中所示)。您可以为数据元素附加标准/自定义编辑器。此外,还有一些“自制”物业网格。

以下是指向如何使用模板的简单示例的链接:http://wblum.org/listbind/net3/index.html

此问题还与运行时控件生成有关:Add WPF control at runtime

答案 1 :(得分:1)

在C#中,控件是简单的对象。最终,XAML中的每个功能都可以编码。 XAML只是描述UI对象及其之间关系的一种更方便的方式。

每个组件都有一个子属性,可用于添加子元素。 向表单添加按钮应该如下所示:

Button myButton= new Button();
form.Children.Add(myButton);

答案 2 :(得分:1)

在WPF中,可以直接映射控件以对象显示,例如我目前拥有,

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

这将自动将我的Clock_t类与UI中的ClockT_View包装在一起。

但是,你往往会发现你需要为你的View提供一些帮助,而你不想污染你的模型,所以有一种模式可以在中间引入一些东西,如果你愿意,可以使用ViewModel。此模式称为MVVM,在Josh Smith's MVVM pattern article

中进行了解释

要回答你的问题,是的,你可以做这样的事情

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

并且会自动尝试显示VoltageChannel,但除非您有一个DataTemplate,否则只能获得其ToString()(通常是类名)六次的结果。而是在某个地方的资源中定义更高的DataTemplate,或者只是尝试

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