0

現在、StackPanelがあり、動的にコントロールを追加しています。(現在、他のスタックパネル、DatePickers、ComboBoxes、TextBoxes、およびLabelsです。)目的は、現在選択されているレポートタイプに基づいて検索基準オプションを動的に生成しようとしていることです。これを行う際に、後でアクセスできるように名前を設定していますが、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;
    }
}

// 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:startDateDatePickerの初期化と追加は次のとおりです。

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は常に反復の私の頼みの綱です。後で、関連するクラスをラップして、(すべてから頻繁に)switchステートメントを削除しました。

于 2013-01-28T16:33:58.367 に答える