I created an employee management program in C# Sharp that has three Forms. Form to displays all the employees in a DataGridView. And Form adds and edits employee data. The third Form displays all the information of a specific employee. I want to use the MVP pattern on the program. What is the best way to do this? Should I assign three layers for each Form or is there a better way?
I have called form.cs, which is related to the editing and adding Form, to the View class of the main Form where all employees are displayed. In order to use the elements of the editing and adding Form in the layers of the Form related to displaying all employees
That is to interact with the editing and adding Form within the same show employees form layers.
EmpPresenter empPresenter;
MEmpView mEmp = new MEmpView();
//Constructor
public EmpView()
{
InitializeComponent();
//size usercControl
this.Size = new Size(1580, 926);
empPresenter = new EmpPresenter(this);
perfomedEvents();
}
private void perfomedEvents()
{
//Search Employee
btn_searchEmp.Click += delegate { SearchEvent?.Invoke(this, EventArgs.Empty); };
txt_SearchEmp.TextChange += delegate { SearchEvent?.Invoke(this, EventArgs.Empty); };
txt_SearchEmp.KeyDown += (sawd,e) =>
{
if (e.KeyCode == Keys.Enter)
SearchEvent?.Invoke(this, EventArgs.Empty);
};
//Add Employee
btn_addEmp.Click += delegate
{
AddEvent?.Invoke(this, EventArgs.Empty);
mEmp.ShowDialog();
};
//Edit Employee
btn_editEmp.Click += delegate
{
EditEvent?.Invoke(this, EventArgs.Empty);
mEmp.ShowDialog();
};
//Delete Employee
btn_deleteEmp.Click += delegate
{
var result = MessageBox.Show($"Are you sure you want to delete ({dgv_emp.CurrentRow.Cells["name"].Value}) Employee?", "Warning", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
if (result == DialogResult.Yes)
{
DeleteEvent?.Invoke(this, EventArgs.Empty);
MessageBox.Show(message,"Deleted",MessageBoxButtons.OK,MessageBoxIcon.Information);
}
};
//Save
mEmp.btnSave.Click += delegate
{
SaveEvent?.Invoke(this, EventArgs.Empty);
if (isSuccessful)
{
string title = isEdit != true ? "Add Employee" : "Edit Employee";
MessageBox.Show(message, title, MessageBoxButtons.OK, MessageBoxIcon.Information);
mEmp.Close();
}
else
MessageBox.Show(message, "Error in input", MessageBoxButtons.OK, MessageBoxIcon.Error);
};
//Cancel
mEmp.btnCancel.Click += delegate
{
CancelEvent?.Invoke(this, EventArgs.Empty);
mEmp.Close();
};
}
//Properties
public string empName
{
get { return mEmp.empName.Text; }
set { mEmp.empName.Text = value; }
}
public string Age
{
get { return mEmp.Age.Text; }
set { mEmp.Age.Text = value; }
}
public bool Male
{
get { return mEmp.Male.Checked; }
set { mEmp.Male.Checked = value; }
}
public byte[] Photo
{
get { return mEmp.GetPhoto(); }
set { mEmp.SetImage(value); }
}
public string Phone
{
get { return mEmp.Phone.Text; }
set { mEmp.Phone.Text = value; }
}
public string Address
{
get { return mEmp.Address.Text; }
set { mEmp.Address.Text = value; }
}
public string JopTitl
{
get { return mEmp.JopTitl.Text; }
set { mEmp.JopTitl.Text = value; }
}
public string Salary
{
get { return mEmp.Salary.Text; }
set { mEmp.Salary.Text = value; }
}
public string DepNo
{
get { return mEmp.DepNo.Text; }
set { mEmp.DepNo.Text = value; }
}
public string SearchValue
{
get { return txt_SearchEmp.Text; }
set { txt_SearchEmp.Text = value; }
}
public bool IsEdit
{
get { return isEdit; }
set { isEdit = value; }
}
public bool IsSuccessful
{
get { return isSuccessful; }
set { isSuccessful = value; }
}
public string Message
{
get { return message; }
set { message = value; }
}
public DataGridView DataGridView
{
get { return dgv_emp; }
set { dgv_emp.DataSource = value; }
}
//events
public event EventHandler SearchEvent;
public event EventHandler AddEvent;
public event EventHandler EditEvent;
public event EventHandler DeleteEvent;
public event EventHandler SaveEvent;
public event EventHandler CancelEvent;
//Method
public void SetDataEmployee(BindingSource empList)
{
dgv_emp.DataSource = empList;
}
Is this considered an incorrect use of MVP Model
Related
I have a set of classes that I am using to deserialize JSON into. My program will periodically look for changes to this JSON file, and if it finds any, will push the new data to the properties of these classes using reflection.
I need to find any new items added to the collection of the Item2 class (SocialExportJSON.SocialExportData.Item2) after a successful update.
My JSON classes look like this (there are more but I want to avoid too big a wall of code):
public class Item2 : INotifyPropertyChanged
{
[JsonProperty("type")]
private string type;
public string Type
{
get
{
return type;
}
set
{
if (type != value)
{
type = value;
RaisePropertyChanged("Type");
}
}
}
[JsonProperty("id")]
private string id;
public string ID
{
get
{
return id;
}
set
{
if (id != value)
{
id = value;
RaisePropertyChanged("ID");
}
}
}
[JsonProperty("postedIso8601")]
private string postedIso8601;
public string PostedIso8601
{
get
{
return postedIso8601;
}
set
{
if (postedIso8601 != value)
{
postedIso8601 = value;
RaisePropertyChanged("PostedIso8601");
}
}
}
[JsonProperty("postedTimestamp")]
private object postedTimestamp;
public object PostedTimestamp
{
get
{
return postedTimestamp;
}
set
{
if (postedTimestamp != value)
{
postedTimestamp = value;
RaisePropertyChanged("PostedTimestamp");
}
}
}
[JsonProperty("engagement")]
private Engagement engagement;
public Engagement Engagement
{
get
{
return engagement;
}
set
{
if (engagement != value)
{
engagement = value;
RaisePropertyChanged("Engagement");
}
}
}
[JsonProperty("source")]
private Source2 source;
public Source2 Source
{
get
{
return source;
}
set
{
if (source != value)
{
source = value;
RaisePropertyChanged("Source");
}
}
}
[JsonProperty("author")]
private Author author;
public Author Author
{
get
{
return author;
}
set
{
if (author != value)
{
author = value;
RaisePropertyChanged("Author");
}
}
}
[JsonProperty("content")]
private Content content;
public Content Content
{
get
{
return content;
}
set
{
if (content != value)
{
content = value;
RaisePropertyChanged("Content");
}
}
}
[JsonProperty("location")]
private Location location;
public Location Location
{
get
{
return location;
}
set
{
if (location != value)
{
location = value;
RaisePropertyChanged("Location");
}
}
}
[JsonProperty("publication")]
private Publication publication;
public Publication Publication
{
get
{
return publication;
}
set
{
if (publication != value)
{
publication = value;
RaisePropertyChanged("Publication");
}
}
}
[JsonProperty("metadata")]
private Metadata metadata;
public Metadata Metadata
{
get
{
return metadata;
}
set
{
if (metadata != value)
{
metadata = value;
RaisePropertyChanged("Metadata");
}
}
}
//Event handling
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged(string property)
{
//Console.WriteLine("Updated");
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property));
}
}
public class SocialExportData : INotifyPropertyChanged
{
[JsonProperty("dataType")]
private string dataType;
public string DataType
{
get
{
return dataType;
}
set
{
if (dataType != value)
{
dataType = value;
RaisePropertyChanged("DataType");
}
}
}
[JsonProperty("id")]
private int id;
public int ID
{
get
{
return id;
}
set
{
if (id != value)
{
id = value;
RaisePropertyChanged("ID");
}
}
}
[JsonProperty("story")]
private Story story;
public Story Story
{
get
{
return story;
}
set
{
if (story != value)
{
story = value;
RaisePropertyChanged("Story");
}
}
}
[JsonProperty("order")]
private string order;
public string Order
{
get
{
return order;
}
set
{
if (order != value)
{
order = value;
RaisePropertyChanged("Order");
}
}
}
[JsonProperty("lifetime")]
private string lifetime;
public string Lifetime
{
get
{
return lifetime;
}
set
{
if (lifetime != value)
{
lifetime = value;
RaisePropertyChanged("Lifetime");
}
}
}
[JsonProperty("maxAge")]
private int maxAge;
public int MaxAge
{
get
{
return maxAge;
}
set
{
if (maxAge != value)
{
maxAge = value;
RaisePropertyChanged("MaxAge");
}
}
}
[JsonProperty("maxSize")]
private int maxSize;
public int MaxSize
{
get
{
return maxSize;
}
set
{
if (maxSize != value)
{
maxSize = value;
RaisePropertyChanged("MaxSize");
}
}
}
[JsonProperty("consumeCount")]
private int consumeCount;
public int ConsumeCount
{
get
{
return consumeCount;
}
set
{
if (consumeCount != value)
{
consumeCount = value;
RaisePropertyChanged("ConsumeCount");
}
}
}
[JsonProperty("consumeInterval")]
private int consumeInterval;
public int ConsumeInterval
{
get
{
return consumeInterval;
}
set
{
if (consumeInterval != value)
{
consumeInterval = value;
RaisePropertyChanged("ConsumeInterval");
}
}
}
[JsonProperty("items")]
private ObservableCollection<Item2> items;
public ObservableCollection<Item2> Items
{
get
{
return items;
}
set
{
if (items != value)
{
items = value;
RaisePropertyChanged("Items");
}
}
}
//Event handling
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged(string property)
{
//Console.WriteLine("Updated");
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property));
}
}
public class SocialExportJSON : INotifyPropertyChanged
{
[JsonProperty("id")]
private string id;
public string ID
{
get
{
return id;
}
set
{
if (id != value)
{
id = value;
RaisePropertyChanged("ID");
}
}
}
[JsonProperty("ttl")]
private int ttl;
public int TTL
{
get
{
return ttl;
}
set
{
if (ttl != value)
{
ttl = value;
RaisePropertyChanged("TTL");
}
}
}
[JsonProperty("serial")]
private long serial;
public long Serial
{
get
{
return serial;
}
set
{
if (serial != value)
{
serial = value;
RaisePropertyChanged("Serial");
}
}
}
[JsonProperty("formatType")]
private string formatType;
public string FormatType
{
get
{
return formatType;
}
set
{
if (formatType != value)
{
formatType = value;
RaisePropertyChanged("FormatType");
}
}
}
[JsonProperty("modifiedIso8601")]
private string modifiedIso8601;
public string ModifiedIso8601
{
get
{
return modifiedIso8601;
}
set
{
if (modifiedIso8601 != value)
{
modifiedIso8601 = value;
RaisePropertyChanged("ModifiedIso8601");
}
}
}
[JsonProperty("modifiedTimestamp")]
private long modifiedTimestamp;
public long ModifiedTimestamp
{
get
{
return modifiedTimestamp;
}
set
{
if (modifiedTimestamp != value)
{
modifiedTimestamp = value;
RaisePropertyChanged("ModifiedTimestamp");
}
}
}
[JsonProperty("timezone")]
private string timezone;
public string Timezone
{
get
{
return timezone;
}
set
{
if (timezone != value)
{
timezone = value;
RaisePropertyChanged("Timezone");
}
}
}
[JsonProperty("dataType")]
private string dataType;
public string DataType
{
get
{
return dataType;
}
set
{
if (dataType != value)
{
dataType = value;
RaisePropertyChanged("DataType");
}
}
}
[JsonProperty("exports")]
private ObservableCollection<SocialExportData> exports;
public ObservableCollection<SocialExportData> Exports
{
get
{
return exports;
}
set
{
if (exports != value)
{
exports = value;
RaisePropertyChanged("Exports");
}
}
}
//Event handling
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged(string property)
{
//Console.WriteLine("Updated");
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property));
}
}
In another class, I have a method to deserialize to a global instance of my JSON class. It looks like this:
public SocialExportJSON socialExportData;
private async void DownloadAndDeserializeJSONAsync()
{
try
{
//Create a web client with the supplied credentials
var exportClient = new WebClient { Credentials = new NetworkCredential(uName, pw), Encoding = Encoding.UTF8};
//Create a task to download the JSON string and wait for it to finish
var downloadTask = Task.Run(() => exportClient.DownloadString(new Uri(eURL)));
downloadTask.Wait();
//Get the string from the task
var JSONString = await downloadTask;
//Create a task to deserialize the JSON from the last task
var DeserializeTask = Task.Run(() => JsonConvert.DeserializeObject<SocialExportJSON>(JSONString));
DeserializeTask.Wait();
SocialExportJSON sej = await DeserializeTask;
//Check the timestamp first to see if we should change the data
if(socialExportData == null)
{
//Get the data from the task
socialExportData = await DeserializeTask;
}
else if(sej.ModifiedTimestamp != socialExportData.ModifiedTimestamp)
{
//Get the data from the task
SocialExportJSON newData = await DeserializeTask;
GetNewItems(newData);
SetNewData(newData);
//Call the exportUpdated event when the task has finished
exportUpdated();
}
}
catch (Exception e)
{
MessageBox.Show(e.Message.ToString());
}
}
In my SetNewData function, shown below, I use reflection to set the properties of my global class. Because I'm setting the whole collection rather than iterating through each of the properties in each of the classes, I can't use the CollectionChanged event to find new items.
public void SetNewData(SocialExportJSON newData)
{
//Loop through each of the properties and copy from source to target
foreach (PropertyInfo pi in socialExportData.GetType().GetProperties())
{
if (pi.CanWrite)
{
pi.SetValue(socialExportData, pi.GetValue(newData, null), null);
}
}
}
Is there a way I can modify my SetNewData function in such a way that it calls CollectionChanged? If not, what would be the best way to go about getting any new additions to my collection of Item2?
In my Main function. I create an instance of my class called SocialExport like so:
SocialExport s = new SocialExport("http://example.json", "example", "example");.
This class is where the global instance of my JSON class is contained, and my event handler is added like so
s.socialExportData.Exports[0].Items.CollectionChanged += CollectionChanged;
Then you are hooking up an event handler for the CollectionChanged event for that particular instance of ObservableCollection<Item2>.
If you create a new ObservableCollection<Item2>, you obviously must hook up an event handler to this one as well. The event handler that is associated with the old object won't be invoked when new items are added to the new instance.
So whenever a new ObservableCollection<Item2> is created, using deserialization or not, you should hook up a new event handler.
You could probably do this in your DownloadAndDeserializeJSONAsync method. The other option would be to create only one instance of the collection and remove and add items from/to this one.
I am trying to reach a foreach but my program never gets inside because my ICollection Coletores is always empty even if I put a lot of stuff in there.
The code where I want to get inside and it is always empty (I want to get inside the second foreach):
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
if (NavigationContext.QueryString.TryGetValue("email", out email))
{
//MessageBox.Show(email);
List<HyperlinkButton> listaLinks = new List<HyperlinkButton>();
AppDataContext db = new AppDataContext();
int i = 0;
HyperlinkButton aux = new HyperlinkButton();
foreach (Pessoa pessoa in db.Pessoas)
{
if (pessoa.Email == email)
{
foreach (Coletor coletor in pessoa.Coletores)
{
aux.Content = "Coletor " + (i + 1).ToString();
aux.FontSize = 24;
aux.NavigateUri = new Uri("/OcorrenciasPage.xaml?coletorId=" + coletor.Id.ToString(), UriKind.RelativeOrAbsolute);
listaLinks.Add(aux);
i++;
}
}
}
ListBox coletores = new ListBox();
coletores.ItemsSource = listaLinks;
stcList.Children.Add(coletores);
}
base.OnNavigatedTo(e);
}
Now the code that I am adding data:
if (txtLat.Text != "" && txtLong.Text != "" && rdNorte.IsChecked == true || rdSul.IsChecked == true && rdLeste.IsChecked == true || rdOeste.IsChecked == true)
{
foreach (var pessoa in db.Pessoas)
{
if (pessoa.Email == email)
{
pessoa.Coletores.Add(coletor);
}
}
db.Coletores.InsertOnSubmit(coletor);
db.SubmitChanges();
NavigationService.Navigate(new Uri("/ColetoresPage.xaml?email=" + email, UriKind.RelativeOrAbsolute));
}
Now, my Pessoa class:
public class Pessoa : INotifyPropertyChanged
{
private int _id;
[Column(IsDbGenerated = true, IsPrimaryKey = true)]
public int Id {
get { return _id;}
set { _id = value;
OnPropertyChanged("Id");
}
}
private string _nome;
[Column]
public string Nome
{
get { return _nome; }
set { _nome = value;
OnPropertyChanged("Nome");
}
}
private string _email;
[Column]
public string Email
{
get { return _email; }
set { _email = value;
OnPropertyChanged("Email");
}
}
private string _senha;
[Column]
public string Senha { get { return _senha; }
set { _senha = value;
OnPropertyChanged("Senha");
}
}
private string _profissao;
[Column]
public string Profissao { get { return _profissao; }
set { _profissao = value;
OnPropertyChanged("Profissao");
}
}
private int _idade;
[Column]
public int Idade { get { return _idade; }
set { _idade = value;
OnPropertyChanged("Idade");
}
}
private string _endereco;
[Column]
public string Endereco { get { return _endereco; }
set { _endereco = value;
OnPropertyChanged("Endereco");
}
}
private string _cidade;
[Column]
public string Cidade { get { return _cidade; }
set { _cidade = value;
OnPropertyChanged("Cidade");
}
}
private string _estado;
[Column]
public string Estado { get { return _estado; }
set { _estado = value;
OnPropertyChanged("Estado");
}
}
private EntitySet<Coletor> _coletores = new EntitySet<Coletor>();
[Association(Name = "FK_Coletores_PessoaColetores", Storage = "_coletores", ThisKey = "Id", OtherKey = "pessoaId")]
public ICollection<Coletor> Coletores
{
get { return _coletores; }
set { _coletores.Assign(value); }
}
private EntitySet<PessoaColetor> _pessoaColetores = new EntitySet<PessoaColetor>();
[Association(Name = "FK_PessoaColetores_Pessoas", Storage = "_pessoaColetores", OtherKey = "pessoaId", ThisKey = "Id")]
private ICollection<PessoaColetor> PessoaColetores
{
get { return _pessoaColetores; }
set { _pessoaColetores.Assign(value); }
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string name)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(name));
}
}
}
The Coletores property on the Pessoa class looks alright. There is also a PessoaColetores property. Are you sure there has been no confusion between the two? Especially with intellisense one might dot or tab the wrong one.
Have you put a break point on the line that actually adds coletors (second code snippet)? Maybe stuff is added to the wrong collection.
Cheers, B.
I populate a data grid with a list of objects that come from a repository like this:
public static IEnumerable<Order> GetOrdersForDataGrid()
{
IEnumerable<Order> query;
using (RSDContext = new RSDContext())
{
query = context.Orders.Include(o=>o.OrderDetails).ToList();
}
return query;
}
When I want to edit an order I pass the selected row to a new window like this:
OrderEditWindow orderEdit = new OrderEditWindow();
orderEdit.SelectedOrder = SelectedOrder;
orderEdit.ShowDialog();
Here I set the DataContext of the Window to:
DataContext = SelectedOrder;
In this window I have another data grid that binds to OrderDetails collection property of Order. The problem is on CRUD operations on OrderDetails. For example, after I add a new orderDetail like this:
private void AddProductDetailButton_OnClick(object sender, RoutedEventArgs e)
{
if (!ValidateProductDetail())
return;
var _selectedProduct = ProductAutoCompleteBox.SelectedItem as Product;
var selectedProduct = ProductsRepository.GetProductById(_selectedProduct.ProductId);
OrderDetail orderDetail = new OrderDetail();
orderDetail.Price = selectedProduct.Price;
orderDetail.ProductCode = selectedProduct.Code;
orderDetail.ProductName = selectedProduct.Name;
orderDetail.Quantity = int.Parse(QuantityNumericUpDown.Value.ToString());
orderDetail.Um = selectedProduct.Um;
orderDetail.Total = selectedProduct.Price * int.Parse(QuantityNumericUpDown.Value.ToString());
orderDetail.Group = selectedProduct.Subgroup.Group.Name;
orderDetail.Subgroup = selectedProduct.Subgroup.Name;
orderDetail.SupplierName = selectedProduct.Supplier.Name;
//orderDetail.Order=SelectedOrder;
//orderDetail.OrderId = SelectedOrder.OrderId;
SelectedOrder.OrderDetails.Add(orderDetail);
ProductAutoCompleteBox.Text = string.Empty;
QuantityNumericUpDown.Value = 1;
ProductAutoCompleteBox.Focus();
}
and then I call the update method from repository:
public static void UpdateOrder(Order order)
{
using (RSDContext context = new RSDContext())
{
context.Orders.Attach(order);
context.Entry(order).State = EntityState.Modified;
context.SaveChanges();
}
}
I get an error about OrderId. If i set manualy the navigation property and the id I don't get an error but changes dont get saved into db.
My Order model look like this:
public class Order : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public Order()
{
_OrderDetails = new ObservableCollection<OrderDetail>();
_OrderDetails.CollectionChanged += _OrderDetails_CollectionChanged;
}
void _OrderDetails_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
if (e.NewItems != null)
AttachProductChangedEventHandler(e.NewItems.Cast<OrderDetail>());
if (e.OldItems != null)
CalcualteTotals();
}
[NotMapped]
public decimal CalculatedTotal
{
get
{
return OrderDetails.Sum(x => x.Total);
}
}
public int OrderId { get; set; }
private int _Number;
public int Number
{
get { return _Number; }
set
{
_Number = value;
NotifyPropertyChanged("Number");
}
}
private DateTime _Date;
public DateTime Date
{
get { return _Date; }
set
{
_Date = value;
NotifyPropertyChanged("Date");
}
}
private bool _Canceled;
public bool Canceled
{
get { return _Canceled; }
set
{
_Canceled = value;
NotifyPropertyChanged("Canceled");
}
}
private string _ClientName;
public string ClientName
{
get { return _ClientName; }
set
{
_ClientName = value;
NotifyPropertyChanged("ClientName");
}
}
private string _ClientPhone;
public string ClientPhone
{
get { return _ClientPhone; }
set
{
_ClientPhone = value;
NotifyPropertyChanged("ClientPhone");
}
}
private string _DeliveryAddress;
public string DeliveryAddress
{
get { return _DeliveryAddress; }
set
{
_DeliveryAddress = value;
NotifyPropertyChanged("DeliveryAddress");
}
}
private decimal _Transport;
public decimal Transport
{
get { return _Transport; }
set
{
_Transport = value;
NotifyPropertyChanged("Transport");
}
}
private decimal _Total;
public decimal Total
{
get { return _Total; }
set
{
_Total = value;
NotifyPropertyChanged("Total");
}
}
private ObservableCollection<OrderDetail> _OrderDetails;
public virtual ObservableCollection<OrderDetail> OrderDetails
{
//get { return _OrderDetails ?? (_OrderDetails = new ObservableCollection<OrderDetail>()); }
get
{
return _OrderDetails;
}
set
{
_OrderDetails = value;
NotifyPropertyChanged("OrderDetails");
}
}
private void AttachProductChangedEventHandler(IEnumerable<OrderDetail> orderDetails)
{
foreach (var p in orderDetails)
{
p.PropertyChanged += (sender, e) =>
{
switch (e.PropertyName)
{
case "Quantity":
case "Price":
case "Total":
CalcualteTotals();
break;
}
};
}
CalcualteTotals();
}
public void CalcualteTotals()
{
NotifyPropertyChanged("CalculatedTotal");
}
public void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this,
new PropertyChangedEventArgs(propertyName));
}
}
}
And my OrderDetail model look like this:
public class OrderDetail : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public int OrderDetailId { get; set; }
public int OrderId { get; set; }
public Order Order { get; set; }
private int _ProductCode;
public int ProductCode
{
get { return _ProductCode; }
set
{
_ProductCode = value;
NotifyPropertyChanged("ProductCode");
}
}
private string _ProductName;
public string ProductName
{
get { return _ProductName; }
set
{
_ProductName = value;
NotifyPropertyChanged("ProductName");
}
}
private string _Um;
public string Um
{
get { return _Um; }
set
{
_Um = value;
NotifyPropertyChanged("Um");
}
}
private decimal _Price;
public decimal Price
{
get { return _Price; }
set
{
_Price = value;
NotifyPropertyChanged("Price");
NotifyPropertyChanged("Total");
}
}
private int _Quantity;
public int Quantity
{
get { return _Quantity; }
set
{
_Quantity = value;
NotifyPropertyChanged("Quantity");
NotifyPropertyChanged("Total");
}
}
private string _SupplierName;
public string SupplierName
{
get { return _SupplierName; }
set
{
_SupplierName = value;
NotifyPropertyChanged("SupplierName");
}
}
private string _Subgroup;
public string Subgroup
{
get { return _Subgroup; }
set
{
_Subgroup = value;
NotifyPropertyChanged("Subgroup");
}
}
private string _Group;
public string Group
{
get { return _Group; }
set
{
_Group = value;
NotifyPropertyChanged("Group");
}
}
public decimal _Total;
public decimal Total
{
get { return Quantity * Price; }
set
{
_Total = value;
NotifyPropertyChanged("Total");
}
}
public void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this,
new PropertyChangedEventArgs(propertyName));
}
}
}
I'm really trying to use some sort of unit of work and I don't understand how i'm supposed to apply CRUD on objects with child collections and keep the UI updated in the same time (by working in a ObservableCollection and using Binding ClientPhone, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged my parent window is updated as I type)
A final working solution:
using (RSDContext context = new RSDContext())
{
var details = order.OrderDetails;
order.OrderDetails = null;
List<int> OriginalOrderDetailsIds =
context.OrderDetails.Where(o => o.OrderId == order.OrderId).Select(o => o.OrderDetailId).ToList();
List<int> CurrentOrderDetailsIds = details.Select(o => o.OrderDetailId).ToList();
List<int> DeletedOrderDetailsIds = OriginalOrderDetailsIds.Except(CurrentOrderDetailsIds).ToList();
context.Entry(order).State = EntityState.Modified;
foreach (var deletedOrderDetailId in DeletedOrderDetailsIds)
{
context.Entry(context.OrderDetails.Single(o => o.OrderDetailId == deletedOrderDetailId)).State = EntityState.Deleted;
}
foreach (OrderDetail detail in details)
{
// Add.
if (detail.OrderDetailId == 0)
{
detail.OrderId = order.OrderId;
context.Entry(detail).State = EntityState.Added;
}
// Update.
else
{
context.Entry(detail).State = EntityState.Modified;
}
}
context.SaveChanges();
}
You could do this way for adding and updating the child, but not sure about deleted order details in the ui. If you don't want to get the order from entity, you need some kind of marking in the OrderDetail for deleted OrderDetail.
using (RSDContext context = new RSDContext())
{
var details = order.OrderDetails;
order.OrderDetails = null;
context.Entry(order).State = EntityState.Modified;
foreach (var detail in details)
{
if (detail.Id == 0)
{
// Adds.
detail.OrderId = order.Id;
context.Entry(detail).State = EntityState.Added;
}
else if (detail.IsDeleted)
// Adds new property called 'IsDeleted'
// and add [NotMapped] attribute
// then mark this property as true from the UI for deleted items.
{
// Deletes.
context.Entry(detail).State = EntityState.Deleted;
}
else
{
// Updates.
context.Entry(detail).State = EntityState.Modified;
}
}
order.OrderDetails = details;
context.SaveChanges();
}
I am using IsolatedStorageSettings to store a contact list for a key in my app. But the app only stores the list till the app is active(i.e. like navigating from one page to another). If I exit the app and again relaunch it, the stored key/contact list is not found. How do i permanently save a list for an app, till the app is installed?
Here is the code of my viewmodel, I am using:
public class ContactsViewModel : ViewModelBase
{
private static IsolatedStorageSettings appSettings = IsolatedStorageSettings.ApplicationSettings;
private List<SavedContact> _SavedContactsList;
public ContactsViewModel()
{
Contacts cons = new Contacts();
cons.SearchAsync(String.Empty, FilterKind.None, null);
cons.SearchCompleted += new EventHandler<ContactsSearchEventArgs>(OnContactSearchCompleted);
SaveSavedContactsCommand = new RelayCommand(OnSaveSavedContacts);
}
private List<SavedContact> GetSavedContacts()
{
if (appSettings.Contains("SavedContacts"))
{
var savedContacts = (List<SavedContact>)appSettings["SavedContacts"];
return savedContacts;
}
else
{
return new List<SavedContact>();
}
}
public RelayCommand SaveSavedContactsCommand { get; set; }
private void OnSaveSavedContacts()
{
if (!SavedContactsList.Any(x => x.IsSelected == true))
{
MessageBox.Show("Please select some contacts and then click on Save button.");
}
else
{
var selectedSavedContacts = SavedContactsList.Where(x => x.IsSelected == true).ToList();
SavedContacts = selectedSavedContacts;
MessageBox.Show("Emergency contact list added successfully.");
App.RootFrame.GoBack();
}
}
void OnContactSearchCompleted(object sender, ContactsSearchEventArgs e)
{
try
{
SavedContactsList = new List<SavedContact>();
var allContacts = new List<Contact>(e.Results.Where(x => x.PhoneNumbers.Count() > 0).OrderBy(c => c.DisplayName));
// var savedContacts = GetSavedContacts();
var savedContacts = SavedContacts;
foreach (Contact contact in allContacts)
{
SavedContact SavedContact = new SavedContact() { Contact = contact };
if (savedContacts.Any(x => x.Contact.PhoneNumbers.ElementAt(0).PhoneNumber == contact.PhoneNumbers.ElementAt(0).PhoneNumber))
{
SavedContact.IsSelected = true;
}
else
{
SavedContact.IsSelected = false;
}
SavedContactsList.Add(SavedContact);
}
}
catch (System.Exception ex)
{
MessageBox.Show("Error in retrieving contacts : " + ex.Message);
}
}
[DataMember]
public List<SavedContact> SavedContactsList
{
get { return _SavedContactsList; }
set
{
_SavedContactsList = value;
RaisePropertyChanged("SavedContactsList");
}
}
private List<SavedContact> SavedContacts
{
get
{
if (appSettings.Contains("SavedContacts"))
{
var savedContacts = (List<SavedContact>)appSettings["SavedContacts"];
return savedContacts;
}
else
{
return new List<SavedContact>();
}
}
set
{
appSettings["SavedContacts"] = value;
}
}
}
And the class SavedContact is followings:
[DataContract]
public class SavedContact : INotifyPropertyChanged
{
public SavedContact() { }
private bool _isSelected;
private Contact _contact;
[DataMember]
public bool IsSelected
{
get
{
return _isSelected;
}
set
{
if (_isSelected != value)
{
_isSelected = value;
OnPropertyChanged("IsSelected");
}
}
}
[DataMember]
public Contact Contact
{
get
{
return _contact;
}
set
{
if (_contact != value)
{
_contact = value;
OnPropertyChanged("Contact");
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
}
Where the view model is bound to a <toolKit: LongListMultiSelector />. The functionality is like, I select some contacts from my longlist multiselector and save it in storage to reuse it later. But if I exit the app and restarts it , the savedContacts returns null. While I navigate other pages in my app, the savedContacts is getting printed.
If I save a list first time , on app relaunch GetSavedContacts() returns a new list.
The problem isn't related to IsolatedStorageSettings or your RelayCommand. Looking in more detail the problem is with serialization and de-serialization of the Contact object. If you update your implementation to something like the example below, you should be fine.
public class ContactsViewModel : ViewModelBase
{
private static IsolatedStorageSettings appSettings = IsolatedStorageSettings.ApplicationSettings;
private List<UserContact> _contactList;
public ContactsViewModel()
{
Contacts cons = new Contacts();
cons.SearchAsync(String.Empty, FilterKind.None, null);
cons.SearchCompleted += new EventHandler<ContactsSearchEventArgs>(OnContactSearchCompleted);
SaveSavedContactsCommand = new RelayCommand(OnSaveSavedContacts);
}
public RelayCommand SaveSavedContactsCommand { get; private set; }
private void OnSaveSavedContacts()
{
if (!Contacts.Any(x => x.IsSelected == true))
{
MessageBox.Show("Please select some contacts and then click on Save button.");
}
else
{
var selectedSavedContacts = Contacts.Where(x => x.IsSelected == true).Select(x => new SavedContact{ Name = x.Contact.DisplayName, PhoneNumber = x.Contact.PhoneNumbers.ElementAt(0).PhoneNumber}).ToList();
SavedContacts = selectedSavedContacts;
MessageBox.Show("Emergency contact list added successfully.");
App.RootFrame.GoBack();
}
}
void OnContactSearchCompleted(object sender, ContactsSearchEventArgs e)
{
try
{
Contacts = new List<UserContact>();
var allContacts = new List<Contact>(e.Results.Where(x => x.PhoneNumbers.Count() > 0).OrderBy(c => c.DisplayName));
foreach (Contact contact in allContacts)
{
UserContact SavedContact = new UserContact() { Contact = contact };
if (SavedContacts.Any(x => x.PhoneNumber == contact.PhoneNumbers.ElementAt(0).PhoneNumber))
{
SavedContact.IsSelected = true;
}
else
{
SavedContact.IsSelected = false;
}
Contacts.Add(SavedContact);
}
}
catch (System.Exception ex)
{
MessageBox.Show("Error in retrieving contacts : " + ex.Message);
}
}
[DataMember]
public List<UserContact> Contacts
{
get { return _contactList; }
set
{
_contactList = value;
RaisePropertyChanged("Contacts");
}
}
public List<SavedContact> SavedContacts
{
get
{
if (appSettings.Contains("SavedContacts"))
{
var savedContacts = (List<SavedContact>)IsolatedStorageSettings.ApplicationSettings["SavedContacts"];
return savedContacts;
}
else
{
return new List<SavedContact>();
}
}
set
{
if (value != null)
{
IsolatedStorageSettings.ApplicationSettings["SavedContacts"] = value;
IsolatedStorageSettings.ApplicationSettings.Save();
}
}
}
}
public class SavedContact
{
public string Name { get; set; }
public string PhoneNumber { get; set; }
}
[DataContract]
public class UserContact : INotifyPropertyChanged
{
public UserContact() { }
private bool _isSelected;
private Contact _contact;
[DataMember]
public bool IsSelected
{
get
{
return _isSelected;
}
set
{
if (_isSelected != value)
{
_isSelected = value;
OnPropertyChanged("IsSelected");
}
}
}
[DataMember]
public Contact Contact
{
get
{
return _contact;
}
set
{
if (_contact != value)
{
_contact = value;
OnPropertyChanged("Contact");
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
}
Key/Value pairs added to the applications IsolatedStorageSettings are persisted until the application is un-installed or the item is removed from the dictionary. This is true for between application restarts and when the device is powered on and off.
Your SaveList method could be simplified to the example below as it's only necessary to check .Contains when retrieving a value from the settings dictionary as it will throw an exception if the entry cannot be found.
private void SaveList()
{
appSettings["SavedContacts"] = urls;
}
Alternatively you could use a property to handle all access to IsolatedStorageSettings using something like the example below:
private IList<Contact> Contacts
{
get
{
return appSettings.Contains("SavedContacts") ? (List<Contact>)appSettings["SavedContacts"] : null;
}
set
{
appSettings["SavedContacts"] = value;
}
}
I have a GridView, radGvA133s, on my main form, MainForm. I would like to be able to double-click on a row of the GridView and have that open up a new form, A133Form, to allow editing of the selected row.
Here is the double-click code:
private void radGvA133s_DoubleClick(object sender, EventArgs e)
{
A133 oA133 = (A133)A133BindingSource.CurrencyManager.List[A133BindingSource.CurrencyManager.Position];
A133Form oA133Form = new A133Form();
oA133Form.NewA133 = oA133;
oA133Form.IsNew = false;
oA133Form.ShowDialog(this);
//On return - if not cancelled, then continue
if (oA133Form.Cancelled != true)
{
this.radGvA133s.Refresh();
}
oA133Form.Dispose();
oA133Form = null;
}
Here is the A133Form code:
public partial class A133Form : Form
{
public A133Form()
{
InitializeComponent();
}
private bool _IsNew;
public bool IsNew
{
get
{
return _IsNew;
}
set
{
_IsNew = value;
}
}
private bool _Cancelled;
public bool Cancelled
{
get
{
return _Cancelled;
}
set
{
_Cancelled = value;
}
}
private A133 _newA133 = new A133();
public A133 NewA133
{
get
{
return _newA133;
}
set
{
_newA133 = value;
}
}
private void A133Form_Load(object sender, EventArgs e)
{
A133DB A133DB = new A133DB();
DataTable dtRSNs = A133DB.GetRSNList();
DataRow drFirstItem = dtRSNs.NewRow();
radComboRSN.DataSource = dtRSNs;
drFirstItem["rsn_id"] = "0";
drFirstItem["rsn_name"] = "";
dtRSNs.Rows.InsertAt(drFirstItem, 0);
radComboRSN.ValueMember = "rsn_id";
radComboRSN.DisplayMember = "rsn_name";
//Set databindings
radComboRSN.DataBindings.Add(new Binding("Text", NewA133, "RSN", true, DataSourceUpdateMode.OnPropertyChanged));
radTxtSubcontractor.DataBindings.Add(new Binding("Text", NewA133, "Subcontractor", true, DataSourceUpdateMode.OnPropertyChanged));
radMTxtCFDANumber.DataBindings.Add(new Binding("Text", NewA133, "CFDANumber", true, DataSourceUpdateMode.OnPropertyChanged));
radCbIncludeCFDA.DataBindings.Add(new Binding("Checked", NewA133, "IncludeCFDA", true, DataSourceUpdateMode.OnPropertyChanged));
radMTxtYear.DataBindings.Add(new Binding("Text", NewA133, "sYear", true, DataSourceUpdateMode.OnPropertyChanged));
radTxtFedAward.DataBindings.Add(new Binding("Text", NewA133, "FedAward", true, DataSourceUpdateMode.OnPropertyChanged));
radCbExceeds.DataBindings.Add(new Binding("Checked", NewA133, "Exceeds", true, DataSourceUpdateMode.OnPropertyChanged));
radDTPDateMHDReceived.DataBindings.Add(new Binding("Value", NewA133, "DateMHDReceived", true, DataSourceUpdateMode.OnPropertyChanged));
radDTPPeriodEnding.DataBindings.Add(new Binding("Value", NewA133, "PeriodEnding", true, DataSourceUpdateMode.OnPropertyChanged));
radDTPDateAudited.DataBindings.Add(new Binding("Value", NewA133, "DateAudited", true, DataSourceUpdateMode.OnPropertyChanged));
radDTPForwardDate.DataBindings.Add(new Binding("Value", NewA133, "ForwardDate", true, DataSourceUpdateMode.OnPropertyChanged));
radTxtSAOPerson.DataBindings.Add(new Binding("Text", NewA133, "SAOPerson", true, DataSourceUpdateMode.OnPropertyChanged));
}
private void radBtnCancel_Click(object sender, EventArgs e)
{
this.Cancelled = true;
this.Close();
}
private void radBtnSave_Click(object sender, EventArgs e)
{
this.Cancelled = false;
bool bValid = true;
foreach(Control control in this.Controls)
{
if (Convert.ToString(control.Tag) == "Required")
{
bool bMissingInfo = false;
if (control is RadDateTimePicker)
{
RadDateTimePicker dtp = control as RadDateTimePicker;
if (dtp.Value.ToString() == "1/1/0001 12:00:00 AM")
{
bMissingInfo = true;
}
}
else
{
if (string.IsNullOrEmpty(control.Text))
{
bMissingInfo = true;
}
}
if (bMissingInfo == true)
{
errorProvider1.SetError(control, "* Required Field");
bValid = false;
}
else
{
errorProvider1.SetError(control, "");
}
}
}
if (bValid == true)
{
bool bSaved = NewA133.SaveData();
if (bSaved == true)
{
this.Close();
}
else
{
MessageBox.Show("There was an error saving the data! If this continues, please contact technical assistance.",
"Error Saving Data", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
else
{
MessageBox.Show("The information you have entered is incomplete. Please fill out all required fields.",
"Missing Information", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
}
}
And, finally, here is the A133 Class code:
#region A133 Collection
public class A133Collection : BindingListView<A133>
{
public A133Collection() : base()
{
}
public A133Collection(List<A133> a133s) : base(a133s)
{
}
public A133Collection(DataTable dt)
{
foreach(DataRow oRow in dt.Rows)
{
A133 a = new A133(oRow);
this.Add(a);
}
}
private int FindMaxId()
{
int maxId = -1;
foreach(A133 a in this)
{
if (a.A133Id > maxId)
{
maxId = a.A133Id;
}
}
return maxId;
}
}
#endregion
#region A133 Class
///<summary>
///Class: A133
///Desc: Manages a single A133 business object
/// Note - 4 states for the object: Unchanged, Added, Deleted, Modified
/// Added flags that a brand new object was added; set prior to db insert
/// Deleted flags that the object was deleted; set after db delete
/// Unchanged is default state
/// Modified flags that props have changed
/// >> The IsDirty indicator looks to see if the object is "modified" or "added"
/// since these are pre-database flags
///</summary>
public class A133 : INotifyPropertyChanged, IEditableObject, IDataErrorInfo
{
//Declare internal class collection object
private A133Collection _A133s = new A133Collection();
//Declare internal class objects
private MHDFMS.BusinessLogic.A133DB _DB = new A133DB();
//Declare internal class props
private int _A133Id;
private string _RSN;
private string _Subcontractor;
private string _CFDANumber;
private string _IncludeCFDA;
private string _Year;
private string _FedAward;
private string _Exceeds;
private string _DateMHDReceived;
private string _PeriodEnding;
private string _DateAudited;
private string _ForwardDate;
private string _SAOPerson;
private int _OldA133Id;
private string _OldRSN;
private string _OldSubcontractor;
private string _OldCFDANumber;
private string _OldIncludeCFDA;
private string _OldYear;
private string _OldFedAward;
private string _OldExceeds;
private string _OldDateMHDReceived;
private string _OldPeriodEnding;
private string _OldDateAudited;
private string _OldForwardDate;
private string _OldSAOPerson;
private bool _Editing;
private string _Error = string.Empty;
private EntityStateEnum _EntityState;
private Hashtable _PropErrors = new Hashtable();
private void FirePropertyChangeNotification(string propName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propName));
}
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
#endregion
public A133()
{
this.EntityState = EntityStateEnum.Unchanged;
}
public A133(DataRow dr)
{
//Populates the business object item from a data row
this.A133Id = Convert.ToInt32(dr["a133_id"]);
this.RSN = dr["rsn"].ToString();
this.Subcontractor = dr["subcontractor"].ToString();
this.CFDANumber = dr["cfda_no"].ToString();
this.IncludeCFDA = dr["include_cfda"].ToString();
this.sYear = dr["year"].ToString();
this.FedAward = dr["fed_award"].ToString();
this.Exceeds = dr["exceeds"].ToString();
if (dr["date_mhd_received"] != null)
{
this.DateMHDReceived = Convert.ToDateTime(dr["date_mhd_received"]).ToShortDateString();
}
if (dr["period_ending"] != null)
{
this.PeriodEnding = Convert.ToDateTime(dr["period_ending"]).ToShortDateString();
}
if (dr["date_audited"] != null)
{
this.DateAudited = Convert.ToDateTime(dr["date_audited"]).ToShortDateString();
}
if (dr["forward_date"] != null)
{
this.ForwardDate = Convert.ToDateTime(dr["forward_date"]).ToShortDateString();
}
this.SAOPerson = dr["sao_person"].ToString();
this.EntityState = EntityStateEnum.Unchanged;
}
#region Public Methods/Constructors
public bool SaveData()
{
bool bSaved = false;
if (this.A133Id == 0)
{
bSaved = _DB.SaveA133Data(this);
}
else
{
bSaved = _DB.SaveA133Data(this);
}
if (bSaved == true)
{
this.EntityState = EntityStateEnum.Unchanged;
}
return bSaved;
}
public bool Delete()
{
bool bSaved = _DB.SaveA133AsInactive(this);
if (bSaved == true)
{
this.EntityState = EntityStateEnum.Deleted;
}
return bSaved;
}
public Int32 A133Id
{
get
{
return _A133Id;
}
set
{
_A133Id = value;
}
}
public string RSN
{
get
{
return _RSN;
}
set
{
_RSN = value;
FirePropertyChangeNotification("RSN");
}
}
public string Subcontractor
{
get
{
return _Subcontractor;
}
set
{
_Subcontractor = value;
FirePropertyChangeNotification("Subcontractor");
}
}
public string CFDANumber
{
get
{
return _CFDANumber;
}
set
{
_CFDANumber = value;
FirePropertyChangeNotification("CFDANumber");
}
}
public string IncludeCFDA
{
get
{
return _IncludeCFDA;
}
set
{
_IncludeCFDA = value;
FirePropertyChangeNotification("IncludeCFDA");
}
}
public string sYear
{
get
{
return _Year;
}
set
{
_Year = value;
FirePropertyChangeNotification("sYear");
}
}
public string FedAward
{
get
{
return _FedAward;
}
set
{
_FedAward = value;
FirePropertyChangeNotification("FedAward");
}
}
public string Exceeds
{
get
{
return _Exceeds;
}
set
{
_Exceeds = value;
FirePropertyChangeNotification("Exceeds");
}
}
public string DateMHDReceived
{
get
{
return _DateMHDReceived;
}
set
{
_DateMHDReceived = value;
FirePropertyChangeNotification("DateMHDReceived");
}
}
public string PeriodEnding
{
get
{
return _PeriodEnding;
}
set
{
_PeriodEnding = value;
FirePropertyChangeNotification("PeriodEnding");
}
}
public string DateAudited
{
get
{
return _DateAudited;
}
set
{
_DateAudited = value;
FirePropertyChangeNotification("DateAudited");
}
}
public string ForwardDate
{
get
{
return _ForwardDate;
}
set
{
_ForwardDate = value;
FirePropertyChangeNotification("ForwardDate");
}
}
public string SAOPerson
{
get
{
return _SAOPerson;
}
set
{
_SAOPerson = value;
FirePropertyChangeNotification("SAOPerson");
}
}
public Boolean IsDirty
{
get
{
return ((this.EntityState != EntityStateEnum.Unchanged) || (this.EntityState != EntityStateEnum.Deleted));
}
}
public enum EntityStateEnum
{
Unchanged,
Added,
Deleted,
Modified
}
public A133Collection A133s
{
get
{
return _A133s;
}
}
void IEditableObject.BeginEdit()
{
if (!_Editing)
{
_OldA133Id = _A133Id;
_OldRSN = _RSN;
_OldSubcontractor = _Subcontractor;
_OldCFDANumber = _CFDANumber;
_OldIncludeCFDA = _IncludeCFDA;
_OldYear = _Year;
_OldFedAward = _FedAward;
_OldExceeds = _Exceeds;
_OldDateMHDReceived = _DateMHDReceived;
_OldPeriodEnding = _PeriodEnding;
_OldDateAudited = _DateAudited;
_OldForwardDate = _ForwardDate;
_OldSAOPerson = _SAOPerson;
}
this.EntityState = EntityStateEnum.Modified;
_Editing = true;
}
void IEditableObject.CancelEdit()
{
if (_Editing)
{
_A133Id = _OldA133Id;
_RSN = _OldRSN;
_Subcontractor = _OldSubcontractor;
_CFDANumber = _OldCFDANumber;
_IncludeCFDA = _OldIncludeCFDA;
_Year = _OldYear;
_FedAward = _OldFedAward;
_Exceeds = _OldExceeds;
_DateMHDReceived = _OldDateMHDReceived;
_PeriodEnding = _OldPeriodEnding;
_DateAudited = _OldDateAudited;
_ForwardDate = _OldForwardDate;
_SAOPerson = _OldSAOPerson;
}
this.EntityState = EntityStateEnum.Unchanged;
_Editing = false;
}
void IEditableObject.EndEdit()
{
_Editing = false;
}
public EntityStateEnum EntityState
{
get
{
return _EntityState;
}
set
{
_EntityState = value;
}
}
string IDataErrorInfo.Error
{
get
{
return _Error;
}
}
string IDataErrorInfo.this[string columnName]
{
get
{
return (string)_PropErrors[columnName];
}
}
private void DataStateChanged(EntityStateEnum dataState, string propertyName)
{
//Raise the event
if (PropertyChanged != null && propertyName != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
//If the state is deleted, mark it as deleted
if (dataState == EntityStateEnum.Deleted)
{
this.EntityState = dataState;
}
if (this.EntityState == EntityStateEnum.Unchanged)
{
this.EntityState = dataState;
}
}
#endregion
}
#endregion
Unfortunately, when I double-click on the GridView, I receive this error: "InvalidCastException was unhandled. Unable to cast object of type 'System.Data.DataRowView' to type 'MHDFMS.BusinessLogic.A133'"
This error occurs at the very first line of the double-click event.
I am at a loss here and have been pulling my hair out for some time. Am I missing something obvious? Is there an easier (or better!) way to achieve my desired result?
Any help is greatly appreciated!
Try this:
DataRowView currentRow = A133BindingSource.CurrencyManager.List[A133BindingSource.CurrencyManager.Position] as DataRowView;
A133Form oA133Form = new A133Form();
oA133Form.NewA133 = new A133(currentRow.Row);
You forgot to post the event handler causing the exception... ;)
But the source of the problem seem quite obvious - you get a DataRowView object from the property grid and try to cast it (maybe by assigning to a variable) to A133 were you probably wanted new A133(DataRow dataRow).