效果:
一、验证、属性变更、
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Controls;
using System.Windows.Data;
using AutomaticConfigurationCore.Model;
namespace AutomaticConfigurationCore.ModelValidationRule
{
public class ProductsValidationRule : ValidationRule
{
public static string errormessage = string.Empty;
/// <summary>
/// 当前列表,判断名称是否有重复的
/// </summary>
public static List<ProductsModel> lpm = new List<ProductsModel>();
//重写时,对值执行验证检查
public override ValidationResult Validate(object value,
System.Globalization.CultureInfo cultureInfo)
{
errormessage = "";
if (value is BindingGroup)
{
BindingGroup group = (BindingGroup)value;
foreach (var item in group.Items)
{
ProductsModel pm = item as ProductsModel;
if (string.IsNullOrEmpty(pm.Name) || string.IsNullOrEmpty(pm.TermType)
|| string.IsNullOrEmpty(pm.Queries))
{
errormessage = "终端名、终端型号、查询帧都不能为空!";
return new ValidationResult(false, errormessage);
}
}
if (lpm.GroupBy(i => i.Name).Where(g => g.Count() > 1).Count() > 0)
{
errormessage = "终端名有重复的!";
//lpm.Remove(lpm[lpm.Count - 1]);
return new ValidationResult(false, errormessage);
}
}
return ValidationResult.ValidResult;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
namespace AutomaticConfigurationCore.Commons
{
[Serializable]
public class NotificationBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged(string propertyName)
{
if (this.PropertyChanged != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Input;
namespace AutomaticConfigurationCore.Commons
{
public class DelegateCommand : ICommand
{
public Action<object> ExecuteCommand = null;
public Func<object, bool> CanExecuteCommand = null;
public event EventHandler CanExecuteChanged;
public bool CanExecute(object parameter)
{
if (CanExecuteCommand != null)
{
return this.CanExecuteCommand(parameter);
}
else
{
return true;
}
}
public void Execute(object parameter)
{
if (this.ExecuteCommand != null) this.ExecuteCommand(parameter);
}
public void RaiseCanExecuteChanged()
{
if (CanExecuteChanged != null)
{
CanExecuteChanged(this, EventArgs.Empty);
}
}
}
}
二、Model层
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using AutomaticConfigurationCore.Commons;
using System.Runtime.Serialization;
namespace AutomaticConfigurationCore.Model
{
[DataContract]
[Serializable]
public abstract class BaseModel : NotificationBase
{
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization;
using System.Windows.Controls;
using System.Windows.Data;
using AutomaticConfigurationCore.Commons;
using System.Collections.ObjectModel;
namespace AutomaticConfigurationCore.Model
{
[DataContract]
[Serializable]
public class ProductsModel : BaseModel
{
/// <summary>
/// 终端名称
/// </summary>
private string name;
[DataMember]
public string Name
{
get { return name; }
set {
name = value;
NotifyPropertyChanged("Name");
}
}
/// <summary>
/// 终端型号
/// </summary>
private string termtype;
[DataMember]
public string TermType
{
get { return termtype; }
set {
termtype = value;
NotifyPropertyChanged("TermType");
}
}
/// <summary>
/// 查询帧
/// </summary>
private string queries;
[DataMember]
public string Queries
{
get { return queries; }
set { queries = value;
NotifyPropertyChanged("Queries");
}
}
/// <summary>
/// 终端变量
/// </summary>
private ObservableCollection<VariableModel> variable;
[DataMember]
public ObservableCollection<VariableModel> Variable
{
get {
return variable;
} set {
variable = value;
NotifyPropertyChanged("Variable");
}
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization;
namespace AutomaticConfigurationCore.Model
{
[DataContract]
[Serializable]
public class VariableModel : BaseModel
{
/// <summary>
/// 变量号
/// </summary>
private int id;
[DataMember]
public int Id
{
get { return id; }
set { id = value;
NotifyPropertyChanged("Id");
}
}
/// <summary>
/// 变量名
/// </summary>
private string name;
[DataMember]
public string Name
{
get { return name; }
set { name = value;
NotifyPropertyChanged("Name");
}
}
/// <summary>
/// 变量说明
/// </summary>
private string description;
[DataMember]
public string Description
{
get { return description; }
set { description = value;
NotifyPropertyChanged("Description");
}
}
/// <summary>
/// 数据类型
/// </summary>
private string vtype;
[DataMember]
public string VType
{
get { return vtype; }
set { vtype = value;
NotifyPropertyChanged("VType");
}
}
/// <summary>
/// 内存地址
/// </summary>
private string link;
[DataMember]
public string Link
{
get { return link; }
set { link = value;
NotifyPropertyChanged("Link");
}
}
/// <summary>
/// 表达式
/// </summary>
private string formula;
[DataMember]
public string Formula
{
get { return formula; }
set { formula = value;
NotifyPropertyChanged("Formula");
}
}
/// <summary>
/// 变量单位
/// </summary>
private string unit;
[DataMember]
public string Unit
{
get { return unit; }
set { unit = value;
NotifyPropertyChanged("Unit");
}
}
/// <summary>
/// 小数位数
/// </summary>
private string digit;
[DataMember]
public string Digit
{
get { return digit; }
set { digit = value;
NotifyPropertyChanged("Digit");
}
}
/// <summary>
/// 零浮点处理范围
/// </summary>
private string zerofloat;
[DataMember]
public string ZeroFloat
{
get { return zerofloat; }
set { zerofloat = value;
NotifyPropertyChanged("ZeroFloat");
}
}
/// <summary>
/// 初始值
/// </summary>
private string initvalue;
[DataMember]
public string InitValue
{
get { return initvalue; }
set { initvalue = value;
NotifyPropertyChanged("InitValue");
}
}
/// <summary>
/// 过滤上限
/// </summary>
private string maxvalue;
[DataMember]
public string MaxValue
{
get { return maxvalue; }
set { maxvalue = value;
NotifyPropertyChanged("MaxValue");
}
}
/// <summary>
/// 过滤下限
/// </summary>
private string minvalue;
[DataMember]
public string MinValue
{
get { return minvalue; }
set { minvalue = value;
NotifyPropertyChanged("MinValue");
}
}
/// <summary>
/// 是否记录
/// </summary>
private bool isrecord;
[DataMember]
public bool IsRecord
{
get { return isrecord; }
set
{
isrecord = value;
NotifyPropertyChanged("IsRecord");
}
}
/// <summary>
/// 记录间隔
/// </summary>
private int recordcycle;
[DataMember]
public int RecordCycle
{
get { return recordcycle; }
set
{
recordcycle = value;
NotifyPropertyChanged("RecordCycle");
}
}
/// <summary>
/// 是否为故障
/// </summary>
private bool isbroken;
[DataMember]
public bool IsBroken
{
get { return isbroken; }
set
{
isbroken = value;
NotifyPropertyChanged("IsBroken");
}
}
}
}
三、ViewModel层
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using AutomaticConfigurationCore.Model;
using AutomaticConfigurationCore.Commons;
using AutomaticConfigurationAPP.Pages;
using System.Windows.Controls;
using System.Data;
using System.Runtime.Serialization;
using AutomaticConfigurationCore.ModelValidationRule;
using System.IO;
using System.Windows;
namespace AutomaticConfigurationAPP.ViewModel
{
public class PageProductsModel:BaseModel
{
public DelegateCommand AddCommand { get; set; }
public DelegateCommand DelCommand { get; set; }
public DelegateCommand SaveCommand { get; set; }
public DelegateCommand LoadCommand{get;set;}
public DelegateCommand SelectionChangedCommand { get; set; }
private List<ProductsModel> productslist;
public List<ProductsModel> ProductsList
{
get { return productslist; }
set
{
productslist = value;
NotifyPropertyChanged("ProductsList");
}
}
private string errormessage;
public string ErrorMessage
{
get { return errormessage; }
set
{
errormessage = value;
NotifyPropertyChanged("ErrorMessage");
}
}
public PageProductsModel()
{
//列表数据源
string xmlDirectory = Environment.CurrentDirectory + "//Products";
IOHelper.CreateDir(xmlDirectory);
ProductsList = new List<ProductsModel>();
FileInfo[] xmlFile = IOHelper.FindXmlFile("Products");
foreach (FileInfo f in xmlFile)
{
ProductsList.Add(SerializeHelper.XMLDeserialize<ProductsModel>("Products", f.Name));
ProductsValidationRule.lpm = ProductsList;
}
//命令
AddCommand = new DelegateCommand();
AddCommand.ExecuteCommand = new Action<object>(Add);
DelCommand = new DelegateCommand();
DelCommand.ExecuteCommand = new Action<object>(Del);
SaveCommand = new DelegateCommand();
SaveCommand.ExecuteCommand = new Action<object>(Save);
LoadCommand = new DelegateCommand();
LoadCommand.ExecuteCommand = new Action<object>(Load);
SelectionChangedCommand = new DelegateCommand();
SelectionChangedCommand.ExecuteCommand = new Action<object>(SelectionChanged);
}
private void Load(object obj)
{
}
private void SelectionChanged(object obj)
{
if (obj != null)
{
if (ProductsList.Where(p => p.Name == obj.ToString()).FirstOrDefault().TermType == "DL/T 645-1997")
{
ProductsList.Where(p => p.Name == obj.ToString()).FirstOrDefault().Queries = "44E9 45E9 46E9 54E9 55E9 56E9 43C3 53C3 43C4 53C4 63E9 64E9 65E9 66E9 73E9 74E9 75E9 76E9 83E9 84E9 85E9 86E9";
}
if (ProductsList.Where(p => p.Name == obj.ToString()).FirstOrDefault().TermType == "DL/T 645-2007")
{
ProductsList.Where(p => p.Name == obj.ToString()).FirstOrDefault().Queries = "33333333 33333433 33333533 33343435 33353435 33363435 33343535 33353535 33363535 33333635 33343635 33353635 33363635 33333735 33343735 33353735 33363735 33333835 33343835 33353835 33363835 33333935 33343935 33353935 33363935";
}
//if (ProductsList.Where(p => p.Name == obj.ToString()).FirstOrDefault().TermType == "ModbusRTU")
//{
// ProductsList.Where(p => p.Name == obj.ToString()).FirstOrDefault().Queries = "";
//}
}
}
/// <summary>
/// 添加新行
/// </summary>
/// <param name="obj"></param>
private void Add(object obj)
{
DataGrid dg = obj as DataGrid;
dg.CanUserAddRows = true;
}
/// <summary>
/// 删除行
/// </summary>
/// <param name="obj"></param>
private void Del(object obj)
{
DataGrid dg = obj as DataGrid;
if (dg.SelectedItem != null)
{
ProductsModel pm = dg.SelectedItem as ProductsModel;
ProductsList.Remove(pm);
ProductsValidationRule.lpm = ProductsList;
dg.Items.Refresh();
IOHelper.DeleteFile("Products", pm.Name + ".xml");
}
else
{
MessageBox.Show("没有选择项");
}
}
/// <summary>
/// 保存行
/// </summary>
/// <param name="obj"></param>
private void Save(object obj)
{
if (string.IsNullOrEmpty(ProductsValidationRule.errormessage))
{
string xmlDirectory = Environment.CurrentDirectory + "//Products";
if (IOHelper.CreateDir(xmlDirectory))
{
IOHelper.deleteTmpFiles(xmlDirectory);
foreach (var v in ProductsList)
{
SerializeHelper.XMLSerialize(v, xmlDirectory + "//" + v.Name+".xml");
}
}
}
else
{
//ErrorMessage = ProductsValidationRule.errormessage;
}
//DataGrid dg = obj as DataGrid;
//dg.CanUserAddRows = false;
//Console.WriteLine(ProductsList.First().TermType);
}
}
}
四、view 层
<Page x:Class="AutomaticConfigurationAPP.Pages.Page_Products"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:AutomaticConfigurationCore.ModelValidationRule;assembly=AutomaticConfigurationCore"
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300"
Title="终端管理">
<Grid x:Name="GridProducts">
<Grid.RowDefinitions>
<RowDefinition Height="40"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!--按钮绑定命令-->
<StackPanel Grid.Row="0" Orientation="Horizontal">
<Button Content="添加" Name="btnAdd" Margin="3" Width="60" Command="{Binding AddCommand}" CommandParameter="{Binding ElementName=dataGridProducts}"/>
<Button Content="保存" Name="btnSave" Margin="3" Width="60" Command="{Binding SaveCommand}" CommandParameter="{Binding ElementName=dataGridProducts}"/>
<Button Content="删除" Name="btnDelete" Margin="3" Width="60" Command="{Binding DelCommand}" CommandParameter="{Binding ElementName=dataGridProducts}"/>
<TextBlock Name="message" Height="25" Text="{Binding ErrorMessage,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Width="100"/>
</StackPanel>
<!--按钮绑定命令-->
<DataGrid x:Name="dataGridProducts" RowStyle="{StaticResource RowStyle}" CanUserAddRows="False" AutoGenerateColumns="False" Grid.Row="1" ItemsSource="{Binding ProductsList}">
<!--DataGrid加载时,绑定命令-->
<i:Interaction.Triggers>
<i:EventTrigger EventName="Loaded">
<i:InvokeCommandAction Command="{Binding LoadCommand}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<!--DataGrid行验证-->
<DataGrid.RowValidationRules>
<local:ProductsValidationRule ValidationStep="UpdatedValue"/>
</DataGrid.RowValidationRules>
<DataGrid.Columns>
<DataGridTextColumn Header="终端名称" Binding="{Binding Name}" ElementStyle="{StaticResource DataGridTextCenter}"/>
<DataGridTemplateColumn Header="终端型号">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox ItemsSource="{StaticResource TermTypeList}" SelectedItem="{Binding TermType, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<i:InvokeCommandAction Command="{Binding (DataContext).SelectionChangedCommand,
RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=Page}}" CommandParameter="{Binding Name}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</ComboBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Header="查询帧" Width="*" Binding="{Binding Queries}" ElementStyle="{StaticResource DataGridTextCenter}"/>
</DataGrid.Columns>
</DataGrid>
</Grid>
</Page>