Create table in wpf app.

vitaminchik 446 Reputation points
2023-04-20T09:46:32.8033333+00:00

Hello. I have a need to custom create a table. To allow the user to add new rows to the table. The table must have 9 columns. And lines should be added by the user. If necessary, the user can add a row without columns (combined). The user must insert text and save it as a file, modify already created lines. Can this be done using the Excel library? I have been looking for ways to do this for a long time. Is it possible to create excel spreadsheet in wpf application and make changes already there? Not in Excel. And is it possible to add dropdown lists in rows? Previously, I wanted to do this by creating a Table from the Documents library programmatically in C#. I created an object of type Table. And I wanted to add the ability to add lines with a click. But now I think that through the use of Excel it will be faster. Speed ​​is important to me right now. To make it faster. But I don't know which way to choose. Can you give me advice on how to proceed and direct? Attached is a picture of what the table should look like.

Windows Presentation Foundation
Windows Presentation Foundation
A part of the .NET Framework that provides a unified programming model for building line-of-business desktop applications on Windows.
2,686 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,370 questions
{count} votes

2 answers

Sort by: Most helpful
  1. RogerSchlueter-7899 1,236 Reputation points
    2023-04-20T10:33:55.3066667+00:00

    You don't need Excel, you need a DataGrid.

    0 comments No comments

  2. Hui Liu-MSFT 41,146 Reputation points Microsoft Vendor
    2023-04-21T09:32:56.0066667+00:00

    Hi,@vitaminchik. Welcome Microsoft Q&A. You could use the DataGrid for data binding and if you want to add an Item, you can use CanUserAddRows="True". You could click directly on the cell to change the value. For drop-down lists, use ComboBox or DataGridComboBoxColumn to realize. The DataGrid for the right column is used to show data updates. Or do you want to use the DataGrid for the DataTable ?

    MainWindow.xaml:

    <Grid>
    <Grid.ColumnDefinitions>
    <ColumnDefinition/>
    <ColumnDefinition/>
    </Grid.ColumnDefinitions>
    <DataGrid Name="dg" ItemsSource="{Binding Infos,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" AutoGenerateColumns="False" CanUserAddRows="True">
    <DataGrid.Columns>
    <DataGridTextColumn Header="No1" Binding="{Binding No1}"/>
    <DataGridTextColumn Header="No2" Binding="{Binding No2}"/>
    <DataGridTextColumn Header="Name" Binding="{Binding Name}"/>
    <DataGridTextColumn Header="Description" Binding="{Binding Description}"/>
    <DataGridComboBoxColumn Header="Equipment" 
                                            SelectedValueBinding="{Binding Id}" 
                                         SelectedValuePath="Id"
                                         DisplayMemberPath="Name"   >
    <DataGridComboBoxColumn.ElementStyle>
    <Style TargetType="{x:Type ComboBox}">
    <Setter Property="ItemsSource" Value="{Binding Path=DataContext.MyEquipments, RelativeSource={RelativeSource AncestorType={x:Type Window}}}" />
    </Style>
    </DataGridComboBoxColumn.ElementStyle>
    <DataGridComboBoxColumn.EditingElementStyle>
    <Style TargetType="{x:Type ComboBox}">
    <Setter Property="ItemsSource" Value="{Binding Path=DataContext.MyEquipments, RelativeSource={RelativeSource AncestorType={x:Type Window}}}" />
    </Style>
    </DataGridComboBoxColumn.EditingElementStyle>
    </DataGridComboBoxColumn>
    <DataGridTextColumn Header="WorkersCategory" Binding="{Binding WorkersCategory}"/>
    <DataGridTextColumn Header="Time" Binding="{Binding Time}"/>
    <DataGridTextColumn Header="PriceRate" Binding="{Binding PriceRate}"/>
    <DataGridTextColumn Header="Specifications" Binding="{Binding Specifications}"/>
    </DataGrid.Columns>
    
    </DataGrid>
    <StackPanel  Grid.Column="1">
        <DataGrid ItemsSource="{Binding Infos,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
    
    

    MainWindow.xaml.cs:

       public partial class MainWindow : Window,INotifyPropertyChanged
    
    {
    
    public MainWindow()
    {
        InitializeComponent();
        infos.Add(new Info() { No1 = "1", No2 = "1", Name = "Text", Description = "TEXT", 
            Equipment = new ObservableCollection<Equi>() {  new Equi(){Id=1, Name="a1"},  new Equi(){Id=2, Name="b1"},  new Equi(){Id=3, Name="c1"}, }, 
            WorkersCategory = "TEXT", PriceRate = "TEXT", Specifications = "TEXT", Time = "TEXT" });
        infos.Add(new Info() { No1 = "2", No2 = "1", Name = "Text", Description = "Text", 
            Equipment = new ObservableCollection<Equi>() {    new Equi(){Id=1, Name="a1"},  new Equi(){Id=2, Name="b1"}, new Equi(){Id=3, Name="c1"},}, 
            WorkersCategory = "TEXT", PriceRate = "TEXT", Specifications = "TEXT", Time = "TEXT" });
        MyEquipments = new ObservableCollection<Equi>()
    {
       new Equi(){Id=1, Name="a1"},
       new Equi(){Id=2, Name="b1"},
       new Equi(){Id=3, Name="c1"},
    };
        DataContext = this;
    
    
    }
    
    
    
    public ObservableCollection<Equi> MyEquipments { get; set; }
    private ObservableCollection<Info> infos = new ObservableCollection<Info>();
    public ObservableCollection<Info> Infos
    {
        get { return infos; }
        set
        {
            if (infos != value)
            {
                infos = value;
                OnPropertyChanged("Infos");
            }
        }
    }
    
    
    public class Equi
    {
        public int Id  { get; set; }
        public string Name { get; set; }
    }
    
    
    public class Info
    {
        public string No1 { get; set; }
        public string No2{ get; set; }
        public string Name{ get; set; }
        public string Description { get; set; }
        public ObservableCollection<Equi> Equipment { get; set; }
        public string WorkersCategory { get; set; }
        public string Time { get; set; }
        public string PriceRate { get; set; }
        public string Specifications { get; set; }
    }
    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged([CallerMemberName] string name = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
    }
    public void CreateTableOfCloth()
    {
        InitializeComponent();
        var myGrid = new Grid();
        RowDefinition myRowDef1 = new RowDefinition();
        RowDefinition myRowDef2 = new RowDefinition();
        myGrid.RowDefinitions.Add(myRowDef1);
        myGrid.RowDefinitions.Add(myRowDef2);
    
        // Creating toolbar.
        ToolBarPanel myToolBarTray = new ToolBarPanel();
        Grid.SetRow(myToolBarTray, 0);
        myToolBarTray.VerticalAlignment = VerticalAlignment.Top;
    
        ToggleButton saveButton = new ToggleButton();
        saveButton.Name = "saveButton";
        saveButton.ToolTip = "Save file";
        Image saveImage = new Image();
        saveImage.Width = 16;
        saveImage.Height = 16;
        BitmapImage bi3 = new BitmapImage();
        bi3.BeginInit();
        bi3.UriSource = new Uri("save.png", UriKind.Relative);
        bi3.EndInit();
        saveImage.Stretch = Stretch.Fill;
        saveImage.Source = bi3;
    
        myToolBarTray.Background = new SolidColorBrush(Color.FromRgb(238, 245, 253));
        myToolBarTray.Height = 50;
    
        StackPanel stackPanel = new StackPanel();
        RichTextBox myRichTextBox = new RichTextBox();
        FlowDocument flowDocument = new FlowDocument();
        {
            var table2 = new Table();
            flowDocument.Blocks.Add(table2);
            table2.CellSpacing = 10;
            table2.Background = Brushes.White;
    
            int score = 1;
            int numberOfColumns = 7;
            for (int i = 0; i < numberOfColumns; i++)
            {
                table2.Columns.Add(new TableColumn());
                if (i % 2 == 0)
                {
                    table2.Columns[i].Background = Brushes.Beige;
                }
                else
                    table2.Columns[i].Background = Brushes.LightSteelBlue;
            }
    
            table2.RowGroups.Add(new TableRowGroup());
            table2.RowGroups[0].Rows.Add(new TableRow());
            TableRow currentRow = table2.RowGroups[0].Rows[0];
            currentRow.Background = Brushes.Silver;
            currentRow.FontSize = 18;
            currentRow.FontWeight = FontWeights.Bold;
            currentRow.Cells.Add(new TableCell(new Paragraph(new Run("table"))));
            currentRow.Cells[0].ColumnSpan = 6;
    
            // Add 2 lines.
            table2.RowGroups[0].Rows.Add(new TableRow());
            currentRow = table2.RowGroups[0].Rows[1];
            // Line formatting after heading.
            currentRow.FontSize = 14;
            currentRow.FontWeight = FontWeights.Bold;
    
            currentRow.Cells.Add(new TableCell(new Paragraph(new Run("Text"))));
            currentRow.Cells.Add(new TableCell(new Paragraph(new Run("Text"))));
            currentRow.Cells.Add(new TableCell(new Paragraph(new Run("Text"))));
            currentRow.Cells.Add(new TableCell(new Paragraph(new Run("Text"))));
            currentRow.Cells.Add(new TableCell(new Paragraph(new Run("Text"))));
            currentRow.Cells.Add(new TableCell(new Paragraph(new Run("Text"))));
    
            table2.RowGroups[0].Rows.Add(new TableRow());
            currentRow = table2.RowGroups[0].Rows[2];
    
            // Global formatting for the row.
            currentRow.FontSize = 12;
            currentRow.FontWeight = FontWeights.Normal;
        }
        myRichTextBox.Document = flowDocument;
        stackPanel.Children.Add(myRichTextBox);
        Grid.SetRow(stackPanel, 1);
        myGrid.Children.Add(myToolBarTray);
        myGrid.Children.Add(stackPanel);
    
        this.Content = myGrid;
        myRichTextBox.SelectAll();
    }
    
    }
    

    The result: User's image

    If the response is helpful, please click "Accept Answer" and upvote it. Note: Please follow the steps in our documentationto enable e-mail notifications if you want to receive the related email notification for this thread.