mark
mark

Reputation: 53

wpf- dynamically create and add new textbox and textblock to grid row when button clicked

I have a grid layout. there are three columns on each row. 1stcolumn contain a TextBox and 2rd and 3rd column contain TextBlock.

I added a new button and what i want to do is that whenever user click on the button it generate a new row that contains a TextBox on 1stcolumn contain and 2rd and 3rd column contain TextBlock.

I am doing this ss I want to get the value(the name) the user have enter on each Textbox, then do some Web Service called to retrieved relevant values to show on the two TextBlocks wihtin the same row.

I already searched few stackoverflow threads related this but mostly suggest you to implement the event handler buttonClicked() by adding new control(e.g. textbox) as an child to the grid layout instead of using MVVM.

I wonder If there is any way I could achieved this using MVVM? any suggestion?

Upvotes: 2

Views: 2710

Answers (1)

JSteward
JSteward

Reputation: 7091

On closer read of the comments above @benPearce pointed out an excellent answer to the same question dynamically add controls. Hopefully a little extra info below will still help.

To add controls dynamically use an ItemsControl or a derivative and bind to a collection of the view model you'd like to use. This is just a real basic example that omits some boilerplate for brevity:

XAML

<Window x:Class="MyWpfApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApplication1"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition Height="3*"/>
        </Grid.RowDefinitions>
        <Button Content="Add New Entry" Command="{Binding AddNewEntryCommand}"/>
        <ItemsControl Grid.Row="1" ItemsSource="{Binding TextEntryItems}">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <TextBlock Text="{Binding Label}"/>
                        <TextBox Text="{Binding Data}"/>
                    </StackPanel>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </Grid>
</Window>

C#

namespace MyWpfApp {
    public class MainWindowViewModel : INotifyPropertyChanged {

        private void AddNewEntry() {
            TextEntryItems.Add(new TextEntryViewModel("NewItem"));
        }

        private ObservableCollection<TextEntryViewModel> textEntryItems;
        public ObservableCollection<TextEntryViewModel> TextEntryItems { get { return textEntryItems; } set { textEntryItems = value; FirePropertyChanged(); } }

        public ICommand AddNewEntryCommand { get { new RelayCommand(AddNewEntry)} }
    }

    public class TextEntryViewModel : INotifyPropertyChanged {

        public TextEntryViewModel(string label) {
            Label = label;
        }

        private string label;
        public string Label { get { return label; } set { label = value; FirePropertyChanged(); } }

        private string data;
        public string Data { get { return data; } set { data = value; FirePropertyChanged(); } }        
    }

}

Upvotes: 1

Related Questions