我是WPF新手并开始学习MVVM概念。
我正在开发一个创建图形对象的应用程序,该图形对象包含来自数据库的数据。
我有一个包含多个标签和组合框的组框。
每个人都应该保留一份来自我的数据库的列表。
对于第一个组合框,我设法使用MVVVM填充该特定列表。
但是如果我已经使用第一个列表启动DataContext,我怎么能填充其他组合框?
我应该为每个ComboBox创建一个ModelView吗?
一般来说,如何动态地将几个组合框绑定到列表?
<Label Grid.Row="0"
Grid.Column="0"
Grid.ColumnSpan="2"
Name="lblTiNam">Test Item Name :</Label>
<TextBox Grid.Row="0"
Grid.Column="2"
Name="tbTiName"
MinWidth="100"
MaxWidth="100"></TextBox>
<Label Grid.Row="1"
Grid.Column="0"
Grid.ColumnSpan="2"
Name="lblTiExStat">Execution Status :</Label>
<ComboBox Grid.Row="1"
Grid.Column="2"
x:Name="cbTiExStat"
MinWidth="100"
MaxWidth="100"
SelectedValuePath="Content"
ItemsSource="{Binding Binding QcLists.FieldList}"
DisplayMemberPath="Name">
</ComboBox>
<Label Grid.Row="2"
Grid.Column="0"
Grid.ColumnSpan="2"
Name="lblTiVersion">Version :</Label>
<ComboBox Grid.Row="2"
Grid.Column="2"
Name="cbTiVersion"
MinWidth="100"
MaxWidth="100"
SelectedValuePath="Content"
SelectedIndex="1">
<ComboBoxItem>To BE Bind From QC</ComboBoxItem>
</ComboBox>
<Label Grid.Row="3"
Grid.Column="0"
Grid.ColumnSpan="2"
Name="lblTiCRID">CRID :</Label>
<ComboBox Grid.Row="3"
Grid.Column="2"
Name="cbTiCRID"
MinWidth="100"
MaxWidth="100"
SelectedValuePath="Content">
<ComboBoxItem>To BE Bind From QC</ComboBoxItem>
</ComboBox>
<Label Grid.Row="4"
Grid.Column="0"
Grid.ColumnSpan="2"
Name="lblTiApplication">Application :</Label>
<ComboBox Grid.Row="4"
Grid.Column="2"
Name="cbTiApplication"
MinWidth="100"
MaxWidth="100"
SelectedValuePath="Content">
<ComboBoxItem>To BE Bind From QC</ComboBoxItem>
</ComboBox>
<Label Grid.Row="5"
Grid.Column="0"
Grid.ColumnSpan="2"
Name="lblTiTestLevel">Test Level :</Label>
<ComboBox Grid.Row="5"
Grid.Column="2"
Name="cbTiTestLevel"
MinWidth="100"
MaxWidth="100"
SelectedValuePath="Content">
<ComboBoxItem>To BE Bind From QC</ComboBoxItem>
</ComboBox>
即时编辑我的qustion以添加更多信息:
内部类TestableItemViewModel { 公共QCLists QcLists { get {return _qcLists; } }
#endregion
#region Constructor
public TestableItemViewModel()
{
_qcconnect = QCConnection.QCConnect.getInstance();
// LoadListSettings();
LoadListSettings( "TS_USER_05");
SaveCommand = new TestableItemSaveDetailsCommand(this);
}
#endregion
private void LoadListSettings(String FieldName)
{
Customization cust = QCConnection.QCConnect.getInstance().GetTD.Customization;
CustomizationFields fields = cust.Fields;
CustomizationListNode node;
CustomizationField field;
field = fields.get_Field("TEST", FieldName);
node = field.List.RootNode;
_qcLists = new QCLists(node.Children, node.Name);
}
}
class QCLists:INotifyPropertyChanged
{
TDAPIOLELib.List _fieldList;
List<String> myTestList;
String listName;
public String ListName
{
get { return listName; }
set { listName = value; }
}
public List<String> MyTestList
{
get { return myTestList; }
set { myTestList = value; }
}
public QCLists(TDAPIOLELib.List List,String name)
{
_fieldList = List;
myTestList = new List<String>();
listName = name;
}
public TDAPIOLELib.List FieldList
{
get
{
return _fieldList;
}
set
{
_fieldList = value;
OnPropertyChanged("FieldList");
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
以及上面xaml背后的代码:
DataContext = new TestableItemViewModel();
这些是我用过的课程。 正如你在我的xaml中看到的那样,第一个combocox绑定到requierd列表,我可以看到 我期望的价值观。 我如何保持绑定其他组合框? 因为我只有一个TestableItemViewModel实例已经绑定到第一个列表,而数据上下文正在使用该列表。 我有其他列表(实际上是4个),我需要绑定到其他控件。 当然,我使用查询获取requierd列表,但这是另一个问题,因为列表名称可以在任何给定的时间更改。 现在我只需要解决5绑定问题。
答案 0 :(得分:2)
在MVVM范例中绑定组合框 - 您应该向ViewModel类添加一个列表,并使用要在组合框中显示的项目填充它。让我用一个例子来解释:
ViewModel中的(应该实现INotifyPropertyChanged接口):
public BindingList<string> Cities { get; set; }
由于您说从数据库中加载了组合框的值,因此您需要确保在值完成加载时在“Cities”上引发PropertyChanged - 这样视图就知道刷新任何绑定的东西财产“城市”。
在视图中:
<Combobox ItemsSource="{Binding Cities}" />
答案 1 :(得分:1)
答案是在WPF和MVVM中,我们不设置各个控件的DataContext
。相反,我们有一个视图模型类的实例,它具有我们需要在UI中显示的所有属性,我们将 设置为DataContext
的{{1}}或查看。
通过这种方式,所有控件都可以访问视图模型中的所有属性,因此我们只需将每个控件的UserControl
属性设置为视图模型中的相关集合属性。 / p>
答案 2 :(得分:0)
如果我理解正确,你想动态地将组合框添加到你的字符串中。
CS:
public class CollectionWrapper<T>
{
private string _title;
public string Title
{
get { return _title; }
set { _title = value; }
}
private IList<T> _collection;
public IList<T> Collection
{
get { return _collection; }
set { _collection = value; }
}
public string DisplayMemeberPath
{
get;set;
}
}
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.DataContext = this;
}
public List<string> GetNewList()
{
return new List<string>
{
"1","2","3","4","1","2","3","4","1","2","3","4","1","2","3","4"
};
}
private void Button_Click(object sender, RoutedEventArgs e)
{
Items.Add(new CollectionWrapper<string> { Collection = GetNewList(), Title = (Items.Count + 1 ).ToString() , DisplayMemeberPath="Content"});
}
private ObservableCollection<CollectionWrapper<string>> _items;
public ObservableCollection<CollectionWrapper<string>> Items
{
get
{
if (_items == null)
_items = new ObservableCollection<CollectionWrapper<string>>();
return _items;
}
}
}
XAML:
<Window.Resources>
<DataTemplate x:Key="listItemTemplate">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Label Content="{Binding Title}"/>
<ComboBox Grid.Column="1" ItemsSource="{Binding Collection}" DisplayMemberPath="{Binding DisplayMemeberPath}"/>
</Grid>
</DataTemplate>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition />
</Grid.RowDefinitions>
<Button Content="Add List" Click="Button_Click"/>
<ScrollViewer Grid.Row="1">
<ItemsControl ItemTemplate="{StaticResource listItemTemplate}" ItemsSource="{Binding Items}"/>
</ScrollViewer>
</Grid>
答案 3 :(得分:0)
实现这一目标的一种方法是,如果你有一个db记录的模型和一个记录列表的模型,即
为方便起见,我将使用Year示例。
class YearModel : INotifyPropertyChanged
{
#region Members
myService.Year _year;
#endregion
#region Properties
public myService.Year Year
{
get { return _year; }
}
public Int32 id
{
get { return Year.id; }
set
{
Year.id = value;
NotifyPropertyChanged("id");
}
}
public String Code
{
get { return Year.Code; }
set
{
Year.Code = value;
NotifyPropertyChanged("Code");
}
}
#region Construction
public YearModel()
{
this._year = new SchoolMonitor_Service.Year
{
id = 0,
Code = "",
};
}
#endregion
}
然后是列表
class YearListModel
{
myService.myServcieClient service = new myService.myServcieClient();
#region Members
private ObservableCollection<YearModel> _years;
#endregion
#region Properties
public ObservableCollection<YearModel> Years
{
get { return _years; }
}
#endregion
#region Construction
public YearListModel()
{
_years = new ObservableCollection<YearModel>();
foreach (SchoolMonitor_Service.Year y in service.GetYearList())
{
_years.Add(new YearModel
{
id = y.id,
Code = y.Code
}
);
}
}
#endregion
}
然后创建一个ViewModel,获取您需要的所有列表我添加了YearGroups作为示例:
class YearFormViewModel
{
public YearListModel YearList { get; set; }
public YearGroupListModel YearGroupList { get; set; }
public YearFormViewModel()
{
YearList = new YearListModel;
YearGroupList = new YearGroupListModel();
}
}
然后,您可以在窗口/页面中获取ViewModel:
xmlns:local="clr-namespace:myProject.Models"
<Page.Resources>
<local:YearFormViewModel x:Key="myViewModel" />
</Page.Resources>
然后相应地绑定:
<ComboBox x:Name="cbYears"
DataContext="{StaticResource ResourceKey=myViewModel}"
ItemsSource="{Binding Path=YearList.Years}"
SelectedValuePath="id"
DisplayMemberPath="Code"/>
<ComboBox x:Name="cbYearGroups"
DataContext="{StaticResource ResourceKey=myViewModel}"
ItemsSource="{Binding Path=YearGroupList.YearGroups}"
SelectedValuePath="id"
DisplayMemberPath="Code"/>