我目前有一个StackPanel,我正在动态添加控件。 (目前其他堆栈面板,DatePickers,ComboBoxes,TextBoxes和Labels。)意图是,我试图根据当前选择的报告类型动态生成搜索critera选项。在这样做我设置名称,以便我可以稍后访问它,但是,我遇到一个问题,我似乎无法获得我想要的所有用户输入控件,没有丢失的东西或崩溃,因为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)...
答案 0 :(得分:3)
如果您正在搜索来自例如您可以使用
替换第一个示例中的for-each循环的FrameworkElementforeach (var child in this.SearchCriteriaStackPanel.Children.OfType<FrameworkElement>())
{
...
}
答案 1 :(得分: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总是我的迭代迭代,以防我想稍后修改它。
我后来包装了相关的类来消除(所有频繁的)switch语句。