【问题标题】:Retrieve values from many dynamically added comboboxes从许多动态添加的组合框中检索值
【发布时间】:2014-08-13 08:39:49
【问题描述】:

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

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; }
    }
}

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

【问题讨论】:

    标签: c# .net wpf list combobox


    【解决方案1】:

    如果您要从ViewModelBase.ViewModelBase 派生您的ObjectStructureHelper,请添加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>
    

    【讨论】:

      【解决方案2】:

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

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

      <DataTemplate DataType="{x:Type YourPrefix:YourClass}">
          <ComboBox ItemsSource="{Binding Items}" SelectedItem="{Binding SelectedItem}" />
      </DataTemplate>
      

      然后您可以将其中一些自定义类实例添加到集合中并将其数据绑定到 ItemsControl.ItemsSource 属性,它们将呈现为一组 ComboBoxes:

      <ItemsControl ItemsSource="{Binding CollectionOfCustomClassInstances}" />
      

      像这样组织您的项目意味着您只需将类的实例添加到集合中,而不是实际的ComboBoxes,因此,当您想查看结果时,您已经拥有所有数据在您访问时...只需查看您的类实例中的 SelectedItem 属性的值,即可了解在每个 ComboBox 中选择了哪些值。

      请参阅 MSDN 上的 Data Binding Overview 页面以获取更多帮助。

      【讨论】:

        猜你喜欢
        • 2015-08-03
        • 1970-01-01
        • 2018-12-22
        • 1970-01-01
        • 2012-12-31
        • 1970-01-01
        • 1970-01-01
        • 2012-12-26
        • 1970-01-01
        相关资源
        最近更新 更多