我必须实现一个应用程序,用户可以从未知的组合框中选择许多不同的值。如果用户单击“加号”按钮,则会出现一个包含五个组合框的新行。如果按下“减号”按钮,则最后一行消失。
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; }
}
}
使用此代码示例,我能够动态添加组合框,但我不知道如何检索每个组合框的选定值。有谁有想法解决我的问题?
答案 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>