2

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?

5
  • 2
    Don't know your application, however, have you considered using a DataGrid? Commented Feb 8, 2017 at 1:08
  • I guess it would be exhausting to do it in MVVM. It is not easy and MVVM is already complicated enough (most of whom I know try to stay as far as possible from it, instead they use only Model-&-View). An event for the button is your easiest way to do it Commented Feb 8, 2017 at 1:08
  • 2
    I wouldn't call MVVM exhausting, there is a bit of setup, but once you have it in place it simplifies things. This answer (stackoverflow.com/a/24961352/4490) seems to provide a solution using MVVM. Commented Feb 8, 2017 at 1:15
  • thanks for the comments. I am actually implementing a Form. And within the form there are CheckBoxes, a Submit Button, an Add button, and group of textbox for user to type in "names" with two TextBlock on the same grid row... the textbox for typing name is actually the one I was talking about. Commented Feb 8, 2017 at 2:10
  • the reason I have an add button is that the form should allow user to provide more than one "name", so when user click add button, it should generate a new textbox for entering new name and it should have bind to list or observable collection i guess? As 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. as Ramin mentioned DataGrid, I am looking at the DataGrid's docuemnts and considering if I should use it instead of grid. Commented Feb 8, 2017 at 2:10

1 Answer 1

1

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(); } }        
    }

}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.