在动态添加的UserControl上访问TextBox.Text

时间:2014-11-18 11:48:07

标签: c# wpf dynamic user-controls

在加载新窗口时,我将动态数量的UserControls(SetInformation)添加到我的窗口,如下所示

public Window_NewWorkoutLine(int NoOfSets, int workoutLineId)
{
    InitializeComponent();

    currentWorkoutLineId = workoutLineId;

    for (int x = 1; x <= NoOfSets; x++)
    {
        SetInformation setInformation = new SetInformation(x);
        StackPanel_Main.Children.Add(setInformation);
    }
}  

每个UserControl包含2个文本框,我需要做的是从每个UserControl上的每个文本框中获取Text属性,并在对数据库的插入查询中使用它们。每个UserControl的数据将添加到数据库中的单独行。

任何想法的人?

提前致谢

3 个答案:

答案 0 :(得分:1)

我认为您可以枚举所有UIElement或&#34; StackPanel_Main&#34;,然后投射它们。 例如(使用System.Linq):

        foreach (SetInformation setInformation in StackPanel_Main.Children.OfType<SetInformation>())
        {
            string txt1 = setInformation.Text1;
            string txt2 = setInformation.Text2;
        }

但我认为最好关联一个&#34;价值对象&#34;到UserControl的每个实例,以将用户界面(UI)与数据分开。例如,你可以用Binding来做到这一点。 首先声明您的类,它将包含您的数据,并实现INotifyPropertyChanged以进行UI集成:

    /// <summary>
    /// This objet contains all useful data
    /// </summary>
    public class InformationValueObject : INotifyPropertyChanged
    {

        private string _text1;
        private string _text2;

        public string Text1
        {
            get { return _text1; }
            set { _text1 = value; OnPropertyChanged("Text1"); }
        }

        public string Text2
        {
            get { return _text2; }
            set { _text2 = value; OnPropertyChanged("Text2"); }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        private void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

然后根据需要将Binding添加到UserControl,例如,您可以像下面那样设置UserControl的DataContext,然后将每个属性绑定到DataContext中的每个TextBox:

public partial class Window_NewWorkoutLine : Window
{

    private List<InformationValueObject> _valueObjects = new List<InformationValueObject>();

    public Window_NewWorkoutLine(int NoOfSets, int workoutLineId)
    {
        InitializeComponent();

        currentWorkoutLineId = workoutLineId;

        for (int x = 1; x <= NoOfSets; x++)
        {
            SetInformation setInformation = new SetInformation(x);
            InformationValueObject vo = new InformationValueObject();
            setInformation.DataContext = _vo;
            _valueObjects.Add(vo);
            StackPanel_Main.Children.Add(setInformation);
        }
    }
}  

通过读取私有集合&#34; _valueObjects&#34;可以很容易地检索值。不再需要枚举用户界面组合。

分离数据和显示非常重要。 我的例子也可以改进很多。 例如,ListView由ScrollViewer内的StackPanel组成(默认情况下),您可以设置&#34; ItemsSource&#34;具有_valueObjects集合的属性,并自定义项模板以使用自定义UserControl。 然后,您可以使用MVVM模型将您的集合绑定到ListBox上再次进行改进。如果您希望能够动态添加或移除项目,也可以使用ObservableCollection<InformationValueObject>代替List<InformationValueObject> ... 我知道这不可能掌握一切,但我认为通过分离数据和可视化来倾向于这些解决方案可能会很棒。

致以最诚挚的问候,

答案 1 :(得分:0)

也许尝试向控件添加公共属性以获取文本框并将其设置为文本框:

    public string Text
    {
        get
        {
            return txtTextBox.Text.ToString();
        }
        set
        {
            txtTextBox.Text = HttpUtility.HtmlDecode(value);
        }
    }

答案 2 :(得分:0)

您可以向用户控件添加访问者:

public class SetInformation{
    private TextBox box1;
    private TextBox box2;

    public string Box1Text{
        get{
            return box1.Text;
        }
    }

    public string Box2Text{
        get{
            return box2.Text;
        }
    }
...
...
}