如何在单击按钮时复制和添加现有的网格元素(C#WPF)

问题描述 投票:0回答:1

我是C#的新手,开始制作WPF应用程序。我当前的应用程序如下所示:

enter image description here

我的目标是每次单击添加字段按钮时,都会生成“月”组合框,“周”复选框和“任务”文本框的副本。创建新行后,groupbox也应进行调整。在我的XAML代码上,所述控件位于名为“ 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>

我从论坛上找到了一种变通方法,可以单独创建控件,但这是一个繁琐的过程,并且效率很低。有什么方法可以复制/克隆网格元素并将其动态添加到后面的代码中吗?谢谢。

c# wpf xaml
1个回答
0
投票

当您想动态创建控件时,您总是会定义一个DataTemplate

最佳解决方案将实现MVVM。为简单起见,我在代码隐藏文件中实现了属性,而不是实现了视图模型。下面的示例将在单击按钮时添加一个新项目。该:

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
  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>
© www.soinside.com 2019 - 2024. All rights reserved.