【发布时间】:2014-09-24 08:18:34
【问题描述】:
我正在开发 WPF,MVVM C# 简单的学习应用程序。
我的前端确实有使用元素“”的表格结构
请参阅下面的“VehicalForm.xaml”。
下面是我的视图代码以及视图模型部分。 (我只提供了必要的文件。如果您需要任何其他文件,请告诉我)
App.xaml.cs
using Seris.ViewModels;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Windows;
namespace Seris
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
public void OnStartup(object sender, StartupEventArgs e)
{
VehicalForm vehicalForm = new VehicalForm();
vehicalForm.DataContext = new VehicalMainViewModel();
vehicalForm.Show();
}
}
}
VehicalForm.xaml
<Window x:Class="Seris.VehicalForm"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<WrapPanel Orientation="Vertical" Margin="10 " >
<Label Content="Vehical No" HorizontalAlignment="Left"/>
<TextBox Name="VehicalNo_Text" Height="23" TextWrapping="Wrap" Text="TextBox" HorizontalAlignment="Left"/>
<Label Content="Model" HorizontalAlignment="Left"/>
<TextBox Name="Model_Text" Height="23" TextWrapping="Wrap" Text="TextBox" HorizontalAlignment="Left" />
<Label Content="Manufacturing Date" HorizontalAlignment="Left"/>
<DatePicker/>
<Label Content="IU No" HorizontalAlignment="Left"/>
<TextBox Height="23" Name="IUNO_Text" TextWrapping="Wrap" Text="TextBox" HorizontalAlignment="Left"/>
<Label Content="Personnel" HorizontalAlignment="Left"/>
<ComboBox Name="Personnel_Combo" HorizontalAlignment="Left" Width="116"/>
<Separator Height="20" RenderTransformOrigin="0.5,0.5" Width="16"/>
<Button Name="Save_Button" Command="{Binding SaveToList}" Content="Save" Width="66"/>
<ListView Height="294" Width="371" >
<ListView Height="294" Width="371" ItemsSource="{Binding listItems, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" >
<ListView.View>
<GridView>
<GridViewColumn Header="Vehical No" DisplayMemberBinding="{Binding VehicalNo}" />
<GridViewColumn Header="Model" DisplayMemberBinding="{Binding Model}" />
<GridViewColumn Header="ManufacturingDate" DisplayMemberBinding="{Binding ManufacturingDate}" />
<GridViewColumn Header="IUNo" DisplayMemberBinding="{Binding IUNo}" />
<GridViewColumn Header="Personnel" DisplayMemberBinding="{Binding Personnel}" />
</GridView>
</ListView.View>
</ListView>
</WrapPanel>
VehicalForm.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace Seris
{
public partial class VehicalForm : Window
{
public VehicalForm()
{
InitializeComponent();
}
}
}
VehicalMainViewModel.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Seris.Models;
using System.Collections.ObjectModel;
using System.Windows.Input;
using Seris.Commands;
using Seris.ViewModels;
namespace Seris.ViewModels
{
public class VehicalMainViewModel : ObservableObject
{
ObservableCollection<VehicalModel> listItems = new ObservableCollection<VehicalModel>();
#region Getter-Setter
private string _VehicalNo;
public string VehicalNo
{
get { return _VehicalNo; }
set
{
if (value != _VehicalNo)
{
_VehicalNo = value.Trim();
if(OnPropertyChanged("VehicalNo"))
listItems.Add(new VehicalModel(VehicalNo, Model, ManufacturingDate, IUNo, PersonnelName));
}
}
}
private string _Model;
public string Model
{
get { return _Model; }
set
{
if (value != _Model)
{
_Model = value.Trim();
OnPropertyChanged("Model");
}
}
}
private DateTime _ManufacturingDate;
public DateTime ManufacturingDate
{
get { return _ManufacturingDate; }
set
{
if (value != _ManufacturingDate)
{
_ManufacturingDate = value;
OnPropertyChanged("ManufacturingDate");
}
}
}
private string _IUNo;
public string IUNo
{
get { return _IUNo; }
set
{
if (value != _IUNo)
{
_IUNo = value.Trim();
OnPropertyChanged("IUNo");
}
}
}
private string _PersonnelName;
public string PersonnelName
{
get { return _PersonnelName; }
set
{
if (value != _PersonnelName)
{
_PersonnelName = value.Trim();
OnPropertyChanged("PersonnelName");
}
}
}
#endregion
private ICommand _saveButton_Command;
public ICommand SaveButton_Command
{
get { return _saveButton_Command; }
set { _saveButton_Command = value; }
}
public void SaveToList(object o1)
{
listItems.Add(new VehicalModel(VehicalNo,Model,ManufacturingDate,IUNo,PersonnelName));
}
public void RemoveFromList()
{
}
public VehicalMainViewModel()
{
VehicalModel vm=new VehicalModel();
SaveButton_Command = new RelayCommand(new Action<object>(SaveToList));
}
}
}
ObservableObject.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Windows;
namespace Seris.Models
{
public abstract class ObservableObject: INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected bool OnPropertyChanged(string propertyName)
{
this.VerifyPropertyName(propertyName);
PropertyChangedEventHandler handler = PropertyChanged;
if(handler!=null)
{
if (propertyName != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
return true;
}
}
return false;
}
public void VerifyPropertyName(string propertyName)
{
if(TypeDescriptor.GetProperties(this)[propertyName]==null)
{
string msg = "Invalid Property Name: " + propertyName;
if (this.ThrowOnInvalidPropertyName)
throw new Exception(msg);
else
Debug.Fail(msg);
}
}
public bool ThrowOnInvalidPropertyName { get; set; }
}
}
VehicalModel.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
namespace Seris.Models
{
public class VehicalModel : ObservableObject
{
#region Getter-Setter
private string _VehicalNo;
public string VehicalNo
{
get { return _VehicalNo; }
set
{
if (value != _VehicalNo)
{
_VehicalNo = value.Trim();
OnPropertyChanged("VehicalNo");
}
}
}
private string _Model;
public string Model
{
get { return _Model; }
set
{
if (value != _Model)
{
_Model = value.Trim();
OnPropertyChanged("Model");
}
}
}
private DateTime _ManufacturingDate;
public DateTime ManufacturingDate
{
get { return _ManufacturingDate; }
set
{
if (value != _ManufacturingDate)
{
_ManufacturingDate = value;
OnPropertyChanged("ManufacturingDate");
}
}
}
private string _IUNo;
public string IUNo
{
get { return _IUNo; }
set
{
if (value != _IUNo)
{
_IUNo = value.Trim();
OnPropertyChanged("IUNo");
}
}
}
private string _PersonnelName;
public string PersonnelName
{
get { return _PersonnelName; }
set
{
if (value != _PersonnelName)
{
_PersonnelName = value.Trim();
OnPropertyChanged("PersonnelName");
}
}
}
#endregion
#region Constructor
public VehicalModel(string VehicalNo, string Model, DateTime ManufacturingDate, string IUNo, string PersonnelName)
{
this.VehicalNo = VehicalNo;
this.Model = Model;
this.ManufacturingDate = ManufacturingDate;
this.IUNo = IUNo;
this.PersonnelName = PersonnelName;
}
public VehicalModel()
{
this.VehicalNo = null;
this.Model = null;
this.ManufacturingDate = DateTime.Now;
this.IUNo = null;
this.PersonnelName = null;
}
#endregion
#region Methods
#region Validate Methods
public bool Validate_VehicalNo()
{
if (matchRE(VehicalNo,"[A-Zz-z][A-Zz-z0-9]{6}"))
return true;
else
return false;
}
public bool Validate_Model()
{
if(Model!=null)
return true;
else
return false;
}
public bool Validate_ManufacturingDate()
{
return true;
}
public bool Validate_IUNo()
{
if(matchRE(IUNo,"[0-9]{10}"))
return true;
else
return false;
}
public bool Validate_PersonnelName()
{
if(matchRE(PersonnelName,"[A-Za-z]+"))
return true;
else
return false;
}
public bool matchRE(string stringToMatch, string regularExpression)
{
Regex regex = new Regex(@regularExpression);
Match match = regex.Match(stringToMatch);
if(match.Success)
return(true);
else
return(false);
}
#endregion
#endregion
}
}
我需要的是
1) 当我更新 VehicalNo 时,应该在表格中添加新行。
2) 如果我以后需要更新每一行的单个元素,这些元素应该在我更新后立即反映在表中,ListView 中是否有内置功能?或者我需要对单个元素(即 VehicalNo、Model、...)使用 List 并使用 ObservableObject 放入一个主 List 保持关注? 我不知道即使它被添加到列表中,并且我已经使用 ObservableObject 实现了 INotifyPropert,为什么它没有反映在前端。
请帮忙。
【问题讨论】:
-
您需要将 VehicalForm.xaml 的
DataContext设置为 ViewModel。并将 ListView 的ItemSource绑定到您要显示的列表(例如ObservableCollection<VehicalModel> listItems)。然后将该列表视图中的每个单独列绑定到VehicalModel的属性 -
user1:我已经正确设置了DataContext。还通过绑定到 lostItems 再次编辑了我的代码。请再次检查问题,如果不正确,请告诉我如何将 ListView 的单个属性绑定到 VehicalModel 的属性。
-
我可以看到问题。当绑定到
listItems时,ListView 中的每一行都会获取该单个项目的数据上下文。在这个例子中,每一行都有一个VehicalModel的数据上下文(这将有助于发布这个类)因此程序试图在你的VehicalModel类上找到属性、VehicalNo、Model 等。我怀疑它们存在的地方。在您的输出窗口中,您可能会看到一个绑定错误,指出在对象 VehicalModel 上找不到属性 VehicalNo -
user1:我更新了。还要求请简单解释一下这个dataContext问题,因为我是初学者。