0

我目前有一个 StackPanel,我正在动态添加控件。(目前还有其他堆栈面板、DatePickers、ComboBoxes、TextBoxes 和 Labels。)我试图根据当前选择的报告类型动态生成搜索条件选项。在这样做时,我正在设置名称,以便稍后可以访问它,但是,我遇到了一个问题,我似乎无法在不丢失某些内容或崩溃的情况下获得所有我想要的用户输入控件,因为 StackPanels 没有t 有一个 Name 属性。

// This one crashes because a child StackPanel doesn't have Name
foreach (var child in this.SearchCriteriaStackPanel.Children)
{
    switch (((Control)child).Name)
    {
        case "startDate":
            this.reports[index].StartDate = ((DatePicker)child).SelectedDate;
            break;
        case "endDate":
            this.reports[index].EndDate = ((DatePicker)child).SelectedDate;
            break;
        case "employeeId":
            this.reports[index].EmployeeId = (int)((ComboBox)child).SelectedValue != 0 ? (int?)((ComboBox)child).SelectedValue : null;
            break;
        case "jobNumber":
            this.reports[index].JobNumber = ((TextBox)child).Text;
            break;
    }
}

.

// This one skips over the DatePickers
foreach (var child in this.SearchCriteriaStackPanel.Children)
{
    switch (((FrameworkElement)child).Name)
    {
        case "startDate":
            this.reports[index].StartDate = ((DatePicker)child).SelectedDate;
            break;
        case "endDate":
            this.reports[index].EndDate = ((DatePicker)child).SelectedDate;
            break;
        case "employeeId":
            this.reports[index].EmployeeId = (int)((ComboBox)child).SelectedValue != 0 ? (int?)((ComboBox)child).SelectedValue : null;
            break;
        case "jobNumber":
            this.reports[index].JobNumber = ((TextBox)child).Text;
            break;
    }
}

我也愿意接受有关如何解决此问题的替代建议。

编辑#1:这里是 startDate DatePicker 的初始化和添加:

var startDateStackPanel = new StackPanel
        {
            Orientation = Orientation.Horizontal,
            Margin = new Thickness(10, 0, 0, 0)
        };
        startDateStackPanel.Children.Add(new Label { Content = "Start Date:" });
        startDateStackPanel.Children.Add(new DatePicker { Width = 120, Name = "startDate" });
this.SearchCriteriaStackPanel.Children.Add(startDateStackPanel);

编辑#2:我可以这样做,但感觉不对......

var list = new List<Control>(this.SearchCriteriaStackPanel.Children.OfType<DatePicker>());
list.AddRange(this.SearchCriteriaStackPanel.Children.OfType<ComboBox>());
list.AddRange(this.SearchCriteriaStackPanel.Children.OfType<TextBox>());

foreach(var child in list)...
4

2 回答 2

3

如果您正在搜索来自例如 FrameworkElement 的后代,您可以将第一个示例中的 for-each 循环替换为

foreach (var child in this.SearchCriteriaStackPanel.Children.OfType<FrameworkElement>())
{
   ...
}
于 2013-01-28T16:34:05.240 回答
1

我解决类似问题的(可能不太理想)方法如下:

foreach (var child in (from Control c in this.SearchCriteriaStackPanel.Children
                       where !(c is StackPanel)
                       select c))
{
    switch (child.Name)
    {
        case "startDate":
            this.reports[index].StartDate = ((DatePicker)child).SelectedDate;
            break;
        case "endDate":
            this.reports[index].EndDate = ((DatePicker)child).SelectedDate;
            break;
        case "employeeId":
            this.reports[index].EmployeeId = (int)((ComboBox)child).SelectedValue != 0 ?(int?)((ComboBox)child).SelectedValue : null;
            break;
        case "jobNumber":
            this.reports[index].JobNumber = ((TextBox)child).Text;
            break;
    }
}

实际上,它跳过了所有不属于具有 Name 属性的类型的子项。你也可以这样做,if(c is Stackpanel) continue;但 Linq 始终是我迭代的 goto,以防我以后想修改它。后来我包装了相关的类以消除(所有频繁的)switch 语句。

于 2013-01-28T16:33:58.367 回答