在 WPF 中动态添加文本框

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24007994/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 11:49:34  来源:igfitidea点击:

Dynamically add textbox in WPF

c#wpftextbox

提问by JohnPaul

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..

我正在动态创建一个文本框。我的网格中有 2 列。如果其他文本框值 =“tea”,我想向该行添加新文本框。我想为相应的行文本框值更改创建新文本框。我无法在此处使用 Tag 获取选定的行。因为我已经出于某种目的使用了 Tag。我对 Tag 不太了解。无论如何,如何将新文本框添加到相应行的 column1?这是我的代码..

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

回答by Nitin

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.

然后在您的 btn_addnew_Click() 方法中,您只需要将此用户控件添加到用户 Grid 并为其分配行和列。文本框的显示/隐藏将由用户控件本身处理。

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

    grid1.Children.Add(userControl );

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

或者,如果您想为 textbox1 设置 Grid.Row 的值,您可以直接将其获取为:

        if (textbox1 != null)
        {
           int row = (int)textbox1.GetValue(Grid.RowProperty);
           Grid.SetRow(txt2, row);
        }

回答by pushpraj

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