0

I just switched from WinForms to WPF. Am trying to add a table like control like below, which should have columns and textboxes to take in user`s inputs. Let me know.

I tried using DataGrid/Grid/FlowControl/ListView but all of them looks to be for binding data, am not displaying data but taking user`s inputs.

Image is the table. enter image description here

It should accept user`s inputs, and should be able to add more textboxes dynamically using C#.

DeSon
  • 147
  • 13
  • `DataGrid` is exactly what you are looking for. Clicking a column by default shows an edit `TextBox` for user input. When _"adding more textboxes"_ means adding columns or rows, then this is simply achieved by adding new data items to the source collection of the `DataGrid`. – BionicCode Jul 30 '19 at 08:11
  • @BionicCode: I could add columns I wanted, but not textboxes as rows to the grid. Where can I find 'new data items'? I see a lot of options, confusing. – DeSon Jul 30 '19 at 08:19

2 Answers2

0

The thing is that wpf his own mentality. I would suggest you learn MVVM first before doing something "serious".

you can achive that behavior easly with datagrid.

Zer0
  • 1,146
  • 6
  • 15
  • Yeah looks like I need to understand MVVM before starting my development work. Thought it`s as easy as WinForms. – DeSon Jul 30 '19 at 08:24
0

This is the simplest version to create a table that would look like your image. You would use styles to style the columns and headers (e.g. header background).

A TableRowData iteme is displayed as a row in the DataGrid.
Each property of this TableRowData type is displayed as a row's column inside the DatGrid.

class TableRowData : INotifyPropertyChanged
{
  private int serialNumber;
  public int SerialNumber
  {
    get => this.serialNumber;
    set
    {
      this.serialNumber = value;
      OnPropertyChanged();
    }
  }

  private int columnOne;
  public int ColumnOne
  {
    get => this.columnOne;
    set
    {
      this.columnOne= value;
      OnPropertyChanged();
    }
  }

  private int columnTwo;
  public int ColumnTwo
  {
    get => this.columnTwo;
    set
    {
      this.columnTwo= value;
      OnPropertyChanged();
    }
  }

  private int columnThree;
  public int ColumnThree
  {
    get => this.columnThree;
    set
    {
      this.columnThree= value;
      OnPropertyChanged();
    }
  }

  public event PropertyChangedEventHandler PropertyChanged;
  protected virtual OnPropertyChanged([CallerMemberName] string propertyName = null)
  {
    this.PropertyChanged?.Invoke();
  }
}

ViewModel.cs

class ViewModel : INotifyPropertyChanged
{
  public ViewModel()
  {
    this.TableRows = new ObservableCollection<TableRowData>();
  }

  // Adding a new TableRowData to the ObservableCollection will immediately add a row to the bound DataGrid
  public void AddRow()
  {
    this.TableRows.Add(new TableRowData());
  }

  private ObservableCollection<TableRowData> tableRows;
  public ObservableCollection<TableRowData> TableRows
  {
    get => this.tableRows;
    set
    {
      this.tableRows= value;
      OnPropertyChanged();
    }
  }

  public event PropertyChangedEventHandler PropertyChanged;
  protected virtual OnPropertyChanged([CallerMemberName] string propertyName = null)
  {
    this.PropertyChanged?.Invoke();
  }
}

MainWindow.xaml

<Window>
  <Window.DataContext>
    <ViewModel />
  </Window.DataContext>

  <StackPanel>
    <Button Click="OnAddButtonClicked" Content="Add Row" />
    <DataGrid ItemsSource="{Binding TableRows}" />
  </StackPanel>
</Window>

MainWindow.xaml.cs

partial class MainWindow : Window
{
  public MainWindow()
  {
    InitializeComponent();
  }

  private void OnAddButtonClicked(object sender, RoutedEventArgs e)
  {
    (this.DataContext as ViewModel)?.AddRow();
  }
}

Ideally you would use a ICommand instead of the Button.Click event handler to invoke the AddRow() method.

BionicCode
  • 1
  • 4
  • 28
  • 44
  • Thanks for the answer. This is when I click on a button, what if if I have to display some textboxes as default? – DeSon Jul 30 '19 at 09:28
  • In the constructor of `ViewModel` change the initialization of `TableRows` to: `this.TableRows = new ObservableCollection() { new TableRowData() };`. This way you can add an arbitrary number of predefined rows to the `DataGrid`. – BionicCode Jul 30 '19 at 11:06