Reputation: 45
I am newbie in C# and started making a WPF application. My current application looks like this:
My goal is to produce a copy of the "month" combobox, "week" checkboxes, and "task" textbox everytime the Add field button was clicked. The groupbox should also adjust once new rows are created. On my XAML code, the said controls are inside a Grid called "control_grid".
<Grid x:Name="control_grid">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="78*" />
<ColumnDefinition Width="119*" />
<ColumnDefinition Width="178*" />
</Grid.ColumnDefinitions>
<ComboBox Name="month_select" Grid.Column="0" SelectedIndex="0" Grid.Row="0" BorderBrush="Aquamarine" BorderThickness="1" Margin="0,0,113.8,0.6" Grid.ColumnSpan="2" />
<GroupBox BorderThickness=".5" BorderBrush="DarkBlue" Grid.Column="1" Margin="10.4,0,24.8,0.6" >
<Grid Margin="0 4 0 0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<CheckBox x:Name="firstw" Grid.Column="0" />
<CheckBox x:Name="secw" Grid.Column="1" />
<CheckBox x:Name="thirdw" Grid.Column="2" />
<CheckBox x:Name="fourthw" Grid.Column="3" />
</Grid>
</GroupBox>
<TextBox x:Name="task_spec" Grid.Column="1" BorderBrush="DarkGray" BorderThickness="1" Margin="107.4,0,0.2,0.6" Grid.ColumnSpan="2" />
</Grid>
I have found a workaround from forums that creates the controls individually, but this is a tedious process and very inefficient. Is there any way to copy/clone the grid elements and add it dynamically on code behind? Thank you.
Upvotes: 0
Views: 542
Reputation: 29028
When you want to create controls dynamically you would always define a DataTemplate
.
The optimal solution would implement MVVM. To keep it simple I implemented the properties in the code-behind file instead of implementing a view model.
The following example will add a new item when the button is clicked:
TaskItem.cs
// Model class that does the data of a task item.
//
// TODO::Implement INotifyPropertyChanged
// and raise PropertyChanged on property changed
class TaskItem : INotifyPropertyChanged
{
// TODO::Define an enumeration Month which contains a field for each month
public ObservableCollection<Month> Months { get; set; }
public Month SelectedMonth { get; set; }
public bool IsFirstWeekSelected { get; set; }
public bool IsSecondWeekSelected { get; set; }
public bool IsThirdWeekSelected { get; set; }
public bool IsFourthWeekSelected { get; set; }
public string TaskSummary { get; set; }
}
MainWindow.xaml.cs
partial class MainWindow
{
public ObservableCollection<TaskIten> TaskItems { get; set; }
public MainWindow()
{
this.DataContext = this;
this.TaskItems = new ObservableCollection<TaskIten>()
{
new TaskItem()
};
}
private void AddTaskItem_OnClick(object sender, RoutedEventArgs e)
{
this.TaskItems.Add(new TaskItem());
}
}
MainWindow.xaml
<Window>
<GroupBox>
<StackPanel>
<Button Click="AddTaskItem_OnClick"
Content="New Task" />
<ListBox ItemsSource="{Binding TaskItems}">
<ListBox.ItemTemplate>
<DataTemplate DataType="{X:Type TaskItem}">
<StackPanel Orientation="Horizontal">
<ComboBox ItemsSource="{Binding Months}"
SelectedItem="{Binding SelectedMonth}" />
<CheckBox IsChecked="{Binding IsFirstWeekSelected}" />
<CheckBox IsChecked="{Binding IsSecondWeekSelected}" />
<CheckBox IsChecked="{Binding IsThirdWeekSelected}" />
<CheckBox IsChecked="{Binding IsFourthWeekSelected}" />
<TextBox Text="{Binding TaskSummary}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</StackPanel>
</GroupBox>
</Window>
Upvotes: 1