0

I am creating a textbox dynamically. I have 2 columns in my grid. I want to add new textbox to the row if the other textbox value="tea". I want to create new textbox to corresponding row textbox value change. I am unable to use Tag to get selected row here. because I have already used Tag for some purpose. I don't have much idea about Tag. Anyhow, how can I add new textbox to the column1 to the corresponding row? This is my code..

    public int count = 1;
    public TextBox txt1;

    private void btn_addnew_Click(object sender, RoutedEventArgs e)
    {

        //Creating Rows..
        RowDefinition row0 = new RowDefinition();
        row0.Height = new GridLength(40);
        grid1.RowDefinitions.Add(row0);

        //Creating columns..
        ColumnDefinition col0 = new ColumnDefinition();
        ColumnDefinition col1 = new ColumnDefinition();

        col0.Width = new GridLength(150);
        col1.Width = new GridLength(250);

        grid1.ColumnDefinitions.Add(col0);
        grid1.ColumnDefinitions.Add(col1);

        int i = count;

        //1st Column TextBox

        txt1 = new TextBox();
        txt1.Margin = new Thickness(10, 10, 0, 0);
        Grid.SetRow(txt1, i);
        Grid.SetColumn(txt1, 0);

        txt1.Tag = txt1;

        txt1.MouseEnter+=txt1_MouseEnter;
        txt1.TextChanged += txt1_TextChanged;
        grid1.Children.Add(txt1);
        count++;
        }

    private void txt1_MouseEnter(object sender, MouseEventArgs e)
    {
        txt1 = ((TextBox)sender).Tag as TextBox;
        popup.IsOpen = true;
    }

    public TextBox txt2;
    private void txt1_TextChanged(object sender, TextChangedEventArgs e)
    {


        if (txt1.Text.ToString() == "Tea")
        {

            txt2 = new TextBox();

         //How to set row here?

            Grid.SetRow(txt2, ??);
            Grid.SetColumn(txt2, 1);

            txt2.Margin = new Thickness(10, 10, 0, 0);
            grid1.Children.Add(txt2);
        }
        else
        {              
            grid1.Children.Remove(txt2);
        }
    }
JohnPaul
  • 77
  • 5
  • 13
  • I would suggest you to use StackPanel in this case, or simply add a row defination and use the count to set the row or perhaps you can use UniformGrid too. – pushpraj Jun 03 '14 at 05:59
  • I am sorry but i am not sure what are you trying to achieve by this.. how will you keep track of data that you will enter in so many textboxes you will add? If you provide the datamodel backing your UI then there will be n number of ways of achieving this elegantly – Nitin Jun 03 '14 at 06:00
  • Nothing much. I just simply want to add a textbox to corresponding row for Textbox value="tea". I dont know how to get the Row index. – JohnPaul Jun 03 '14 at 06:17
  • check this pls too http://stackoverflow.com/questions/11095189/adding-controls-dynamically-in-wpf-mvvm/11095460#11095460 – blindmeis Jun 03 '14 at 07:51

2 Answers2

1

If you just want to achieve this, then more elegant way will be to add the user control to your application like below:

<UserControl x:Class="WpfApplication4.TestUserControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <TextBox Name="TextBox1"/>
        <TextBox Grid.Column="1">
            <TextBox.Style>
                <Style TargetType="TextBox">
                    <Setter Property="Visibility" Value="Collapsed"/>
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding Text, ElementName=TextBox1, UpdateSourceTrigger=PropertyChanged}" Value="tea">
                            <Setter Property="Visibility" Value="Visible"/>
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </TextBox.Style>
        </TextBox>

    </Grid>
</UserControl>

then in your btn_addnew_Click() method, you just need to add this usercontrol to user Grid and assign row and column to it. Showing/Hiding of textbox will be taken care of by teh user control itself.

    var userControl = new MyUserControl();
    userControl .Margin = new Thickness(10, 10, 0, 0);
    Grid.SetRow(userControl , i);

    grid1.Children.Add(userControl );

OR if you want to have value of Grid.Row for textbox1 you can get it directly as:

        if (textbox1 != null)
        {
           int row = (int)textbox1.GetValue(Grid.RowProperty);
           Grid.SetRow(txt2, row);
        }
Nitin
  • 18,344
  • 2
  • 36
  • 53
  • I am creating textbox Dynamically.. not in XAML – JohnPaul Jun 03 '14 at 07:00
  • in wpf, whatever we try to do in code behind can be achieved in xaml more efficiently , may i know is there any specific reason you dont want to use xaml? – Nitin Jun 03 '14 at 07:02
  • I am new to WPF. and i have programmed like this way. its very difficult to go back and re program. Please help me to identify the Selected row for my above question. In future i will try your answer – JohnPaul Jun 03 '14 at 07:05
  • can i achieve this by Tag? and i have already used tag for some other purpose. will it affect? help me. i am not much good in Dotnet – JohnPaul Jun 03 '14 at 07:08
  • hmm.. you have textbox in your Tag and you want to the next textbox in the same row as the TextBox in your Tag right? – Nitin Jun 03 '14 at 07:10
  • if it is in 2nd row, i want to add new textbox in 2nd row's first column. if it is 5th row i want the textbox to add in 5th row. As per the Textbox value=Tea, i want to add new textbox – JohnPaul Jun 03 '14 at 07:26
  • Thanks.. it finally works when i use, int row = (int)textbox1.GetValue(Grid.RowProperty); Grid.SetRow(txt2, row); – JohnPaul Jun 03 '14 at 08:43
  • 2
    glad it helped... just a friendly suggestion, if you have started working with WPF, learn MVVM, it is amazing.. you will be surprised to see wonders xaml and mvvm pattern do :) – Nitin Jun 03 '14 at 08:45
0

Attached properties can be used to store such information so define an attached property in the class

    public static int GetGridRow(DependencyObject obj)
    {
        return (int)obj.GetValue(GridRowProperty);
    }

    public static void SetGridRow(DependencyObject obj, int value)
    {
        obj.SetValue(GridRowProperty, value);
    }

    // Using a DependencyProperty as the backing store for GridRow.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty GridRowProperty =
        DependencyProperty.RegisterAttached("GridRow", typeof(int), typeof(ViewModel), new PropertyMetadata(0));

then use it to store the value of the row

private void btn_addnew_Click(object sender, RoutedEventArgs e)
{
    //1st Column TextBox

    txt1 = new TextBox();
    Grid.SetRow(txt1, i);
    SetGridRow(text1, i);
    ...
    grid1.Children.Add(txt1);
    count++;
}

then use it when u need it

//How to set row here?

Grid.SetRow(txt2, GetGridRow(txt1));
Grid.SetColumn(txt2, 1);
pushpraj
  • 13,458
  • 3
  • 33
  • 50
  • i am getting error in, typeof(ViewModel). it asks me to add assembly – JohnPaul Jun 03 '14 at 06:12
  • Since i do not know your class so I put ViewModel as reference. you may replace it your view model class or code behind class name (MainWindow) etc or create a new class inheriting DependencyObject if needed. – pushpraj Jun 03 '14 at 06:19
  • i dont want any inherit. i just simply want the Row index value. could you please make the code little bit clear? I just want to set the row value for selected row – JohnPaul Jun 03 '14 at 06:24
  • replacing `ViewModel` with name of your class should work in your case. eg. `MainWindow` – pushpraj Jun 03 '14 at 06:34
  • no its not working even if i replaced MainWindow. it simply add 1st textbox. I am unable to create after one. only one textbox value created – JohnPaul Jun 03 '14 at 06:43
  • I see an error `int count = 1;` instead of 0. For me it is working fine after set to 0. However I would recommend you the solution posted by @nit. I wonder why I didn't think that way. That is more WPF way. – pushpraj Jun 03 '14 at 07:01
  • By the way what is the class name in which this code is implemented? and what is the base class for it? – pushpraj Jun 03 '14 at 07:47