动态添加文本框并在发生时更新绑定

时间:2013-08-05 13:20:45

标签: c# silverlight silverlight-5.0

首先,这仅用于测试目的

我有一个xaml页面,其中只包含一个按钮和2个stackpanel 我们的想法是拥有一个类,该类将具有与之关联的代码和名称。将查询代码,并根据结果显示适当数量的文本框。我需要能够在最后添加名称到文本框并保存列表。

这是我当前的代码,它按照我希望的方式创建文本框,但在填写完成后保存列表时不太确定

XAML                                                                                                               

    <StackPanel x:Name="StackSG" Grid.Row="1" Grid.Column="0">
        <ListBox ItemsSource="{Binding StackSG}" />
    </StackPanel>
    <StackPanel x:Name="StackSGName" Grid.Row="1" Grid.Column="1">
        <ListBox ItemsSource="{Binding StackSGName}" />
    </StackPanel>

    <Button x:Name="Generate" Content="Generate" Height="23" Width="75" Grid.Row="0" Grid.Column="0" 
            Command="{Binding Path=GenerateSGKeys}"/>
</Grid>
</UserControl>

它连接到我的viewmodel,看起来像这样

public class stackpnl : Notify
{
    private IEnumerable stackSG;
    public IEnumerable StackSG
    {
        get { return stackSG; }
        set { stackSG = value; OnNotifyPropertyChanged("StackSG"); }
    }

    private IEnumerable stackSGName;
    public IEnumerable StackSGName
    {
        get { return stackSGName; }
        set { stackSGName = value; OnNotifyPropertyChanged("StackSGName"); }
    }

    private DelegateCommand generateSGKeys;
    public ICommand GenerateSGKeys
    {
        get { return generateSGKeys; }
    }

    private IEnumerable allotments;
    public IEnumerable Allotments
    {
        get { return allotments; }
        set { allotments = value; OnNotifyPropertyChanged("Allotments"); }
    }

    TextBox txtSGName = new TextBox();

    public stackpnl()
    {
        generateSGKeys = new DelegateCommand(Generate, OnGenerate);
        StackSG = new List<TextBox>();
        StackSGName = new List<TextBox>();
    }

    private bool OnGenerate(object obj)
    {
        return true;
    }

    public class Allotment
    {
        #region Properties
        public string AllotmentName { get; set; }
        public string AllotmentCode { get; set; }
        #endregion
    }

    private void Generate(object obj)
    {
        IList<TextBox> StackSGTmp = new List<TextBox>();
        IList<TextBox> StackSGNameTmp = new List<TextBox>();

        IList<Allotment> newList = new List<Allotment>();

        int st = 10;
        for (int i = 0; i < st; i++)
        {
            newList.Add(new Allotment() { AllotmentCode = string.Format("{0}{1}", "Code", i.ToString()), AllotmentName = string.Format("{0}{1}", "Code", i.ToString()) });
        }

        foreach (var Allotment in newList)
        {
            TextBox txtSG = new TextBox();
            txtSG.Name = string.Format(Allotment.AllotmentCode);
            txtSG.Height = 25;
            txtSG.Width = 75;
            txtSG.Text = string.Format(Allotment.AllotmentCode);
            txtSG.Visibility = System.Windows.Visibility.Visible;
            StackSGTmp.Add(txtSG);

            //Add SG name textboxes                       
            txtSGName = new TextBox();
            txtSGName.Name = string.Format(string.Format("{0}{1}", Allotment.AllotmentCode, Allotment.AllotmentName));
            txtSGName.Height = 25;
            txtSGName.Width = 75;
            txtSGName.SetBinding(TextBox.TextProperty, new Binding(Allotment.AllotmentName) { Mode = BindingMode.TwoWay });
            txtSGName.Visibility = System.Windows.Visibility.Visible;
            txtSGName.KeyDown += new KeyEventHandler(txtSGName_KeyDown);
            StackSGNameTmp.Add(txtSGName);
        }

        StackSG = StackSGTmp;
        StackSGName = StackSGNameTmp;            
    }

    void txtSGName_KeyDown(object sender, KeyEventArgs e)
    {
        BindingExpression binding = (sender as TextBox).GetBindingExpression(TextBox.TextProperty);
        binding.UpdateSource();
    }
}

1 个答案:

答案 0 :(得分:0)

您需要做的是使用ListBox的ItemTemplate来显示适当的内容。您的ListBox不应绑定到TextBoxes的集合,而是绑定到Allotments的集合。

将xaml更新为

<ListBox ItemsSource="{Binding Allotments}" Grid.Row="1">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="*"/>
                    <ColumnDefinition Width="*"/>
                </Grid.ColumnDefinitions>
            </Grid>
            <TextBox Text="{Binding AllotmentCode}"/>
            <TextBox Text="{Binding AllotmentName}" Grid.Column="2"/>
        </DataTemplate
    </ListBox.ItemTemplate>
</ListBox>

注意我删除了用于包装ListBox的StackPanel,因为它不需要。然后,在您的代码中,您将删除StackSG和StackSGName属性,并在Generate方法中填充Allotments属性。