C# 在遍历容器时,如何仅检索具有Name属性的控件?

C# 在遍历容器时,如何仅检索具有Name属性的控件?,c#,.net,wpf,C#,.net,Wpf,我目前有一个StackPanel,我正在动态添加控件。(目前还有其他堆栈面板、日期选择器、组合框、文本框和标签。)目的是,我正在尝试根据当前选择的报告类型动态生成搜索准则选项。在这样做的过程中,我设置了名称,以便以后可以访问它,但是,我遇到了一个问题,即我似乎无法获得我想要的所有用户输入控件,而不会丢失某些内容或崩溃,因为StackPanels没有name属性 // This one crashes because a child StackPanel doesn't have Name for

我目前有一个StackPanel,我正在动态添加控件。(目前还有其他堆栈面板、日期选择器、组合框、文本框和标签。)目的是,我正在尝试根据当前选择的报告类型动态生成搜索准则选项。在这样做的过程中,我设置了名称,以便以后可以访问它,但是,我遇到了一个问题,即我似乎无法获得我想要的所有用户输入控件,而不会丢失某些内容或崩溃,因为StackPanels没有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;
    }
}

我也愿意接受关于如何解决这个问题的其他建议

编辑#1: 以下是startDate日期选择器的初始化和添加:

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)...
var list=新列表(this.SearchCriteriaStackPanel.Children.OfType());
list.AddRange(this.SearchCriteriaStackPanel.Children.OfType());
list.AddRange(this.SearchCriteriaStackPanel.Children.OfType());
foreach(列表中的变量子项)。。。
我解决类似问题的方法(可能不太理想)如下所示:

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属性类型的子级。如果(c是Stackpanel)continue,您也可以使用
执行该操作但Linq总是我迭代的目标,以防我以后要修改它。
后来,我包装了相关类,以消除(所有到频繁)switch语句。

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

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属性类型的子级。如果(c是Stackpanel)continue,您也可以使用
执行该操作但Linq总是我迭代的目标,以防我以后要修改它。

后来,我包装了相关的类,以消除(所有到频繁)switch语句。

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

foreach (var child in this.SearchCriteriaStackPanel.Children.OfType<FrameworkElement>())
{
   ...
}
foreach(此.SearchCriteriaStackPanel.Children.OfType()中的var child)
{
...
}

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

foreach (var child in this.SearchCriteriaStackPanel.Children.OfType<FrameworkElement>())
{
   ...
}
foreach(此.SearchCriteriaStackPanel.Children.OfType()中的var child)
{
...
}

您可以反射[使用反射]对象,并检查属性名称是否存在开关((字符串)child.GetType().GetProperty(“name”).GetValue(child,null))。。。仍然跳过DatePickers您可以反射[使用反射]您的对象并检查属性名称是否存在开关((字符串)child.GetType().GetProperty(“name”).GetValue(child,null))。。。仍然跳过DatePickers我可能遗漏了一些东西,但是当我得到type()的子项时,它不包括DatePickers抱歉,我在考虑Winforms。试试吧。由于某些原因,不包括DatePickersStrange。在我的测试项目中(由按钮、标签、文本框和日期选择器组成),它包括在内。刚才选中的MSDN:DatePicker是从控件派生的,控件派生自FrameworkElement。可能您的日期选择器是另一个未迭代的控件的子控件。我可能遗漏了一些内容,但当我得到type()的子控件时,它不包括日期选择器抱歉,我在Winforms中思考。试试吧。由于某些原因,不包括DatePickersStrange。在我的测试项目中(由按钮、标签、文本框和日期选择器组成),它包括在内。刚才选中的MSDN:DatePicker是从控件派生的,控件派生自FrameworkElement。可能您的DatePicker是您未迭代的另一个控件的子控件。它引发InvalidCastException:“无法将类型为'System.Windows.Controls.StackPanel'的对象强制转换为类型为'System.Windows.Controls.control'。”@选中的将强制转换移动到select子句中:
来自this.SearchCriteriaStackPanel.Children where中的对象c!(c是StackPanel)选择(Control)c
它会抛出一个InvalidCastException:“无法将'System.Windows.Controls.StackPanel'类型的对象强制转换为'System.Windows.Controls.Control'类型。”@选中的将强制转换移动到select子句中:
来自this.SearchCriteriaStackPanel.Children where中的对象c!(c为堆叠面板)选择(控制)c