从许多动态添加的组合框中检索值

时间:2014-08-13 08:39:50

标签: c# .net wpf list combobox

我必须实现一个应用程序,用户可以从未知的组合框中选择许多不同的值。如果用户单击“加号”按钮,则会出现一个包含五个组合框的新行。如果按下“减号”按钮,则最后一行消失。

XAML:

<WrapPanel Margin="6,6,0,3">
    <Button Command="{Binding AddTextBoxRowCommand}">
        <Image Source="pack://application:,,,/Images/Dialogs/FI_Hinzufuegen_16x16.png" Width="16" Height="16" />
    </Button>
    <Button IsEnabled="{Binding IsRemoveButtonEnabled}" Command="{Binding RemoveTextBoxRowCommand}" Margin="6,0,0,0">
        <Image Source="pack://application:,,,/Images/Dialogs/FI_Loeschen_16x16.png" Width="16" Height="16" />
    </Button>
</WrapPanel>

<!-- Segment und Feld auswahl -->
<ItemsControl ItemsSource="{Binding TextBoxRowCollection}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <WrapPanel>
                <ComboBox SelectedItem="SelectedSegmentList1" ItemsSource="{Binding Path=SegmentList1}" DisplayMemberPath="SegmentName" SelectedValuePath="SegmentFile" />
                <ComboBox SelectedItem="SelectedFieldList1" ItemsSource="{Binding Path=FieldList1}" DisplayMemberPath="FieldName" SelectedValuePath="Type" />
                <ComboBox SelectedItem="SelectedOperationList" ItemsSource="{Binding Path=DZOperationList}" DisplayMemberPath="OpName" SelectedValue="OpType" />
                <ComboBox SelectedItem="SelectedSegmentList2"  ItemsSource="{Binding Path=SegmentList2}" DisplayMemberPath="SegmentName" SelectedValuePath="SegmentFile" />
                <ComboBox SelectedItem="SelectedFieldList2" ItemsSource="{Binding Path=FieldList2}" DisplayMemberPath="FieldName" SelectedValuePath="Type" />
            </WrapPanel>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

视图模型:

using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Windows.Input;
using DataAccessLayer.DirectoryParser;
using DataAccessLayer.Settings;
using Model;
using ViewModelBase;

namespace ViewModel
{
    public class ModalDialogValueViewModel : ViewModelBase.ViewModelBase
    {
        private RelayCommand addTextBoxRowCommand;
        private RelayCommand removeTextBoxRowCommand;

        private bool isRemoveButtonEnabled;

        private OperationModel opModel;
        private Settings settings;
        private List<Segment> segments;
        private List<Field> fields;

        /// <summary>
        /// Initialisiert das ModalDialogValueViewModel
        /// </summary>
        public ModalDialogValueViewModel()
        {
            settings = new Settings();
            opModel = new OperationModel();

            Segments = PKSegmentParser.GetSegments(settings.PKDirectory, "PROD");

            TextBoxRowCollection = new ObservableCollection<ObjectStructureHelper>();
            TextBoxRowCollection.Add(new ObjectStructureHelper(Segments, Fields, opModel.OpList, Segments, Fields));

            this.PropertyChanged += new PropertyChangedEventHandler(modalDialogValueViewModel_PropertyChanged);
        }

        public bool IsRemoveButtonEnabled
        {
            get { return isRemoveButtonEnabled; }
            set
            {
                if (isRemoveButtonEnabled != value)
                {
                    isRemoveButtonEnabled = value;
                    OnPropertyChanged("IsRemoveButtonEnabled");
                }
            }
        }

        public ObservableCollection<ObjectStructureHelper> TextBoxRowCollection { get; set; }
        public List<Segment> Segments
        {
            get { return segments; }
            set
            {
                if ((segments == null && value != null) || !segments.SequenceEqual(value))
                {
                    segments = value;
                    OnPropertyChanged("Segments");
                }
            }
        }

        public List<Field> Fields
        {
            get { return fields; }
            set
            {
                if ((fields == null && value != null) || !fields.SequenceEqual(value))
                {
                    fields = value;
                    OnPropertyChanged("Fields");
                }
            }
        }

        public ICommand AddTextBoxRowCommand
        {
            get
            {
                if (addTextBoxRowCommand == null)
                    addTextBoxRowCommand = new RelayCommand(p => ExecuteAddFieldRowCommand());

                return addTextBoxRowCommand;
            }
        }

        public ICommand RemoveTextBoxRowCommand
        {
            get
            {
               if (removeTextBoxRowCommand == null)
                   removeTextBoxRowCommand = new RelayCommand(p => ExecuteRemoveTextBoxRowCommand());

               return removeTextBoxRowCommand;
            }
        }

        /// <summary>
        /// Fügt eine Zeile mit für weitere Feld-Verknüpfungen hinzu
        /// </summary>
        private void ExecuteAddFieldRowCommand()
        {
            TextBoxRowCollection.Add(new ObjectStructureHelper(Segments, Fields, opModel.OpList, Segments, Fields));
            if (TextBoxRowCollection.Count > 1)
                IsRemoveButtonEnabled = true;
        }

        /// <summary>
        /// Entfernt eine Zeile von Feld-Verknüpfungen
        /// </summary>
        private void ExecuteRemoveTextBoxRowCommand()
        {
            var count = TextBoxRowCollection.Count;
            if (count > 1)
                TextBoxRowCollection.RemoveAt(count - 1);

            if (count == 2)
                IsRemoveButtonEnabled = false;
        }

        /// <summary>
        /// ModalDialogValueViewModel PropertyChanged EventHandler
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void modalDialogValueViewModel_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "")
            {

            }
        }
    }
}

ObjectStructureHelper类

using System.Collections.Generic;
using DataAccessLayer;
using DataAccessLayer.DirectoryParser;

namespace Model
{
    public class ObjectStructureHelper
    {
        public ObjectStructureHelper(List<Segment> sList1, List<Field> fList1, List<DZOperation> opList, List<Segment> sList2, List<Field> fList2)
        {
            SegmentList1 = sList1;
            FieldList1 = fList1;
            DZOperationList = opList;
            SegmentList2 = sList2;
            FieldList2 = fList2;
        }

        public List<Segment> SegmentList1 { get; set; }
        public List<Field> FieldList1 { get; set; }
        public List<DZOperation> DZOperationList { get; set; }
        public List<Segment> SegmentList2 { get; set; }
        public List<Field> FieldList2 { get; set; }
    }
}

使用此代码示例,我能够动态添加组合框,但我不知道如何检索每个组合框的选定值。有谁有想法解决我的问题?

2 个答案:

答案 0 :(得分:1)

在WPF中,我们通常使用数据元素而不是UI元素。因此,不要编写代码来动态添加ComboBox元素,而是让代码添加数据元素,然后提供包含DataTemplate的{​​{1}}。

如果您声明一个自定义类,其中包含填充ComboBox并管理其选定值所需的所有相关属性,那么您可以为该类型声明ComboBox,以呈现{{ 1}}每次遇到你的一个类实例时:

DataTemplate

然后,您可以将一些自定义类实例添加到集合中,并将数据绑定到ComboBox属性,它们将呈现为一组<DataTemplate DataType="{x:Type YourPrefix:YourClass}"> <ComboBox ItemsSource="{Binding Items}" SelectedItem="{Binding SelectedItem}" /> </DataTemplate> es:

ItemsControl.ItemsSource

像这样组织你的项目意味着你只需要将你的类的实例添加到集合中,而不是实际的ComboBox es因此,当你想要查看结果时,你已经拥有了所有的您访问的数据...只需查看类实例中<ItemsControl ItemsSource="{Binding CollectionOfCustomClassInstances}" /> 属性的值,即可找出每个ComboBox中选择的值。

请参阅MSDN上的Data Binding Overview页面以获取进一步的帮助。

答案 1 :(得分:1)

如果您要从ObjectStructureHelper派生ViewModelBase.ViewModelBase,请通过ComboBoxes添加要绑定到的SelectedItem的属性。

public class ObjectStructureHelper : ViewModelBase.ViewModelBase
{
    public Segment     SelectedSegmentList1  // property implementation with propertychanged
    public Field       SelectedFieldList1    // property implementation with propertychanged
    public DZOperation SelectedOperationList // property implementation with propertychanged
    public Segment     SelectedSegmentList2  // property implementation with propertychanged
    public Field       SelectedFieldList2    // property implementation with propertychanged
}

并按照以下方式更新您的模板:

<DataTemplate>
    <WrapPanel>
         <ComboBox SelectedItem="{Binding SelectedSegmentList1}" ItemsSource="{Binding Path=SegmentList1}" DisplayMemberPath="SegmentName" />
         <ComboBox SelectedItem="{Binding SelectedFieldList1}" ItemsSource="{Binding Path=FieldList1}" DisplayMemberPath="FieldName" />
         <ComboBox SelectedItem="{Binding SelectedOperationList}" ItemsSource="{Binding Path=DZOperationList}" DisplayMemberPath="OpName" />
         <ComboBox SelectedItem="{Binding SelectedSegmentList2}"  ItemsSource="{Binding Path=SegmentList2}" DisplayMemberPath="SegmentName" />
         <ComboBox SelectedItem="{Binding SelectedFieldList2}" ItemsSource="{Binding Path=FieldList2}" DisplayMemberPath="FieldName" />
    </WrapPanel>
</DataTemplate>