Using PostSharp NotifyPropertyChanged, how can you hook into the OnPropertyChanged event - inotifypropertychanged

I am trying to get at the OnPropertyChanged event so that I can mark my class as modified.
[NotifyPropertyChanged]
Public Class Employee
{
private bool hasChange;
public string FirstName { get; set; }
public string LastName { get; set; }
private static void OnPropertyChanged(object sender, PropertyChangedEventArgs e)
{
hasChange = true;
}
}
The OnPropertyChanged is most likely wrong but hopefully you get the idea of what I am trying to do?
Thanks,
James

You need to provide your own OnPropertyChanged method with the same signature as the one generated by PostSharp. As a result, PostSharp will not generate the method and will use your implementation instead. This also means that you need to raise the event in the method yourself.
[NotifyPropertyChanged]
public class Employee : INotifyPropertyChanged
{
private bool hasChange;
public string FirstName { get; set; }
public string LastName { get; set; }
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
hasChange = true;
PropertyChangedEventHandler handler = this.PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}

Related

xamarin.forms binding to class property not working

In my XamarinForms project I am trying to bind a label text to a property of a class. when I pass in the object to my view the label is not being populated. can someone see what I am doing wrong?
In my view model I have
class ManagerLevelPageViewModel : INotifyPropertyChanged
{
private UserSelections _MyUserSelections;
public UserSelections MyUserSelections
{
get { return _MyUserSelections; }
set {
_MyUserSelections = value;
NotifyPropertyChanged();
}
}
public ManagerLevelPageViewModel(UserSelections _temp)
{
MyUserSelections = _temp;
MyUserSelections.selectedClientName = _temp.selectedClientName;
//myUserSelections = _myUserSelections;
//SetValues();
}
here is the class
public class UserSelections
{
public int selectedClientId { get; set; }
public string selectedClientName { get; set; }
public string selectedClientShortCode { get; set; }
public decimal selectedClientPL { get; set; }
public string TopdayIdentifier { get; set; }
}
here is the view.cs
ManagerLevelPageViewModel vm;
public ManagerLevelPage (UserSelections _myUserSelections)
{
vm = new ManagerLevelPageViewModel(_myUserSelections);
InitializeComponent ();
BindingContext = vm;
DownloadData();
}
lastly here is the xaml
<Label Text="{Binding MyUserSelections.ClientName}"/>
notify property changed
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}

Deserialization Error while returning the Object from WCF Service

I'm getting below shown error while returning the Activity object array.Not able understand where things are going wrong.Can any one help me with this .
Here is the error
End element 'ActivityTypeId' from namespace
'http://schemas.datacontract.org/2004/07/BusinessEntities' expected.
Found element 'a:Code' from namespace
'http://schemas.datacontract.org/2004/07/BusinessEntities'. Line 1,
position 450.
UI Related code:
protected void Page_Load(object sender, EventArgs e)
{
TimeSheetManagementServiceClient serviceClient = new TimeSheetManagementServiceClient("WSHttpBinding_ITimeSheetManagementService");
Activity[] activities=serviceClient.GetActivities();
GridView1.DataSource = activities;
GridView1.DataBind();
}
WCFService code
public class TimeSheetManagementService:ITimeSheetManagementService
{
public BusinessEntities.Activity[] GetActivities()
{
TimeSheetManagementDataController controller= new TimeSheetManagementDataController();
var activities = controller.GetActivities().Select(activity => new BusinessEntities.Activity()
{
Code = activity.Code,
Description = activity.Description,
Status =
(EntityStatus)
Enum.Parse(typeof(EntityStatus), ((activity.Status==true) ? 0 : 1).ToString()),
ActivityTypeId = new BusinessEntities.ActivityType()
{
Code=activity.ActivityType.Code,
Description = activity.ActivityType.Description,
Name = activity.ActivityType.Name
}
});
return activities.ToArray();
}
}
Service Contract
[ServiceContract]
interface ITimeSheetManagementService
{
[OperationContract]
Activity[] GetActivities();
}
Data Contract
[DataContract]
public class Activity
{
[DataMember]
public string Code { get; set; }
[DataMember]
public string Description { get; set; }
[DataMember]
public EntityStatus Status { get; set; }
[DataMember]
public ActivityType ActivityTypeId { get; set; }
}
[DataContract]
public enum EntityStatus
{
[EnumMember]
Active=0,
[EnumMember]
Inactive=1
}
[DataContract]
public class ActivityType
{
[DataMember]
public string Code { get; set; }
[DataMember]
public string Name { get; set; }
[DataMember]
public string Description { get; set; }
}
i`m not sure but i think the issue is the alphabetical order of the datamember of your Activity class. just for testing, consider specifying the order property in the Datamember attribute.
http://msdn.microsoft.com/en-us/library/ms729813%28v=vs.90%29.aspx
hope this will help

NServiceBus, Could not find a saga for the message type

My saga below is not handling the ValidateRegistration and ValidateRegistration commands. I see the "Could not find a saga for the message type Registrations.Messages.ValidateRegistration with id ..." message.
Is my configuration to find saga not correct? Please help!
Thanks
PS: I am using the generic host in the registration process and I am using NServiceBus.Lite profile.
public class EndpointConfig : IConfigureThisEndpoint, AsA_Publisher, IWantCustomInitialization
{
#region Implementation of IWantCustomInitialization
public void Init()
{
var kernel = new StandardKernel();
kernel.Load(new BackendModule());
//Configure.Instance.Configurer.ConfigureProperty<RegistrationSaga>(x => x.Factory, kernel.Get<IAggregateRootFactory>());
Configure.With().NinjectBuilder(kernel);
}
#endregion
}
public class RegistrationSagaData : IContainSagaData
{
#region Implementation of ISagaEntity
public virtual Guid Id { get; set; }
public virtual string Originator { get; set; }
public virtual string OriginalMessageId { get; set; }
public virtual RegistrationID RegistrationID { get; set; }
public virtual bool IsValidated { get; set; }
public virtual string RegistrationType { get; set; }
#endregion
}
public class RegistrationSaga : Saga<RegistrationSagaData>,
IAmStartedByMessages<StartRegistration>,
IHandleMessages<ValidateRegistration>,
IHandleMessages<CancelRegistration>
{
public RegistrationFactory Factory { get; set; }
public override void ConfigureHowToFindSaga()
{
ConfigureMapping<StartRegistration>(data => data.RegistrationID, registration => registration.ID);
ConfigureMapping<ValidateRegistration>(data => data.RegistrationID, registration => registration.ID);
ConfigureMapping<CancelRegistration>(data => data.RegistrationID, registration => registration.ID);
}
#region Implementation of IMessageHandler<StartRegistration>
public void Handle(StartRegistration message)
{
Data.IsValidated = false;
Data.RegistrationType = message.RegistrationType;
Bus.SendLocal(new CreateRegistration
{
RegistrationType = message.RegistrationType,
ID = message.ID
});
Console.WriteLine("======> handled StartRegistration");
}
#endregion
#region Implementation of IMessageHandler<ValidateRegistration>
public void Handle(ValidateRegistration message)
{
MarkAsComplete();
Console.WriteLine("======> handled ValidateRegistration");
}
#endregion
#region Implementation of IMessageHandler<CancelRegistration>
public void Handle(CancelRegistration message)
{
Console.WriteLine("======> handled CancelRegistration");
MarkAsComplete();
}
#endregion
}
Your handler for StartRegistration is not adding RegistrationID to the Saga's Data. So your override of ConfigureHowToFindSaga is mapped on a property that's has no value when the other commands are handled.
Just today I heard that Ninject doesn't handle setter injection out of the box - try switching it over to constructor injection and see if that works.

WCF possibly serialization related issue

On server I have the following class
public class A
{
string a1 {get; set ;}
string a2 {get; set;}
}
I have defined a service with the following operation contract
[OperationContract]
public list<A> GetAll()
{
return new List<A> {new A {a1="1", a2="2"}, new A{a1="3", a2="4"}};
}
in the reference there is defined a shallow copy of A in the following way
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")]
[System.Runtime.Serialization.DataContractAttribute(Name="GetAll", Namespace="http://schemas.datacontract.org/2004/07/SomeModel")]
[System.SerializableAttribute()]
public partial class A: object, System.Runtime.Serialization.IExtensibleDataObject, System.ComponentModel.INotifyPropertyChanged {
[System.NonSerializedAttribute()]
private System.Runtime.Serialization.ExtensionDataObject extensionDataField;
[System.Runtime.Serialization.OptionalFieldAttribute()]
private string A1Field;
[System.Runtime.Serialization.OptionalFieldAttribute()]
private string A2Field;
[global::System.ComponentModel.BrowsableAttribute(false)]
public System.Runtime.Serialization.ExtensionDataObject ExtensionData {
get {
return this.extensionDataField;
}
set {
this.extensionDataField = value;
}
}
[System.Runtime.Serialization.DataMemberAttribute()]
public string A1{
get {
return this.A1Field;
}
set {
if ((object.ReferenceEquals(this.A1Field, value) != true)) {
this.A1Field= value;
this.RaisePropertyChanged("A1");
}
}
}
[System.Runtime.Serialization.DataMemberAttribute()]
public string A2{
get {
return this.A2Field;
}
set {
if ((object.ReferenceEquals(this.A2Field, value) != true)) {
this.A2Field= value;
this.RaisePropertyChanged("A2");
}
}
}
public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
protected void RaisePropertyChanged(string propertyName) {
System.ComponentModel.PropertyChangedEventHandler propertyChanged = this.PropertyChanged;
if ((propertyChanged != null)) {
propertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
}
}
}
On the client I call the service.GetAll() and I use the shallow copy of A, defined in the proxy which defines my model for a view. the call is something similar to
ActionResult GetAll()
{
List<A> allAs = service.GetAll();
return new View (allAs);
}
However the list on the client is always emtpy. What is the problem?
You should define your data class, A as a datacontract:
[DataContract]
public class A
{
[DataMember]
public string a1 {get; set ;}
[DataMember]
public string a2 {get; set ;}
}
On the class you will need DataContract attribute from System.Runtime.Serialization.DataContractAttribute namespace.
Some thing like this
[DataContract]
public class A
{
[DataMember]
public string a1 {get; set ;} //This should be public
[DataMember]
public string a2 {get; set;}//This should be public
}
Read more on MSDN

JSON.Net - DeserializeObject Format

I'm using JSON.Net to try and deserialize some survey responses from SurveyGizmo.
Here's a snapshot of the data I'm reading in:
{"result_ok":true,
"total_count":"44",
"page":1,
"total_pages":1,
"results_per_page":50,
"data":[
{"id":"1",
"contact_id":"",
"status":"Complete",
"is_test_data":"0",
"datesubmitted":"2011-11-13 22:26:53",
"[question(59)]":"11\/12\/2011",
"[question(60)]":"06:15 pm",
"[question(62)]":"72",
"[question(63)]":"One",
"[question(69), option(10196)]":"10",
I've setup a class as far as datesubmitted but I'm not sure how to setup the class to deserialize the questions given that the amount of questions will change? I also need to capture the option if it's present.
I'm using this code to use the JSON.NET Deserialize function:
Dim responses As Responses = JsonConvert.DeserializeObject(Of Responses)(fcontents)
Classes:
Public Class Responses
Public Property result_OK As Boolean
Public Property total_count As Integer
Public Property page As Integer
Public Property total_pages As Integer
Public Property results_per_page As Integer
Public Overridable Property data As List(Of surveyresponse)
End Class
Public Class SurveyResponse
Public Property id As Integer
Public Property status As String
Public Property datesubmitted As Date
End Class
This trick to support totally crazy mappings is to use JsonConverter and completely replace the parsing for that object, (I apologize for the C#, but I'm no good at VB syntax):
class Program
{
static void Main(string[] args)
{
var result = JsonConvert.DeserializeObject<Responses>(TestData);
}
const string TestData = #"{""result_ok"":true,
""total_count"":""44"",
""page"":1,
""total_pages"":1,
""results_per_page"":50,
""data"":[
{""id"":""1"",
""contact_id"":"""",
""status"":""Complete"",
""is_test_data"":""0"",
""datesubmitted"":""2011-11-13 22:26:53"",
""[question(59)]"":""11\/12\/2011"",
""[question(60)]"":""06:15 pm"",
""[question(62)]"":""72"",
""[question(63)]"":""One"",
""[question(69), option(10196)]"":""10"",
}]}";
}
[JsonObject]
class Responses
{
public bool result_ok { get; set; }
public string total_count { get; set; }
public int page { get; set; }
public int total_pages { get; set; }
public int results_per_page { get; set; }
public SurveyResponse[] Data { get; set; }
}
[JsonObject]
// Here is the magic: When you see this type, use this class to read it.
// If you want, you can also define the JsonConverter by adding it to
// a JsonSerializer, and parsing with that.
[JsonConverter(typeof(DataItemConverter))]
class SurveyResponse
{
public string id { get; set; }
public string contact_id { get; set; }
public string status { get; set; }
public string is_test_data { get; set; }
public DateTime datesubmitted { get; set; }
public Dictionary<int, string> questions { get; set; }
}
class DataItemConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(SurveyResponse);
}
public override bool CanRead
{
get { return true; }
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var value = (SurveyResponse)existingValue;
if (value == null)
{
value = new SurveyResponse();
value.questions = new Dictionary<int, string>()
}
// Skip opening {
reader.Read();
while (reader.TokenType == JsonToken.PropertyName)
{
var name = reader.Value.ToString();
reader.Read();
// Here is where you do your magic
if (name.StartsWith("[question("))
{
int index = int.Parse(name.Substring(10, name.IndexOf(')') - 10));
value.questions[index] = serializer.Deserialize<string>(reader);
}
else
{
var property = typeof(SurveyResponse).GetProperty(name);
property.SetValue(value, serializer.Deserialize(reader, property.PropertyType), null);
}
// Skip the , or } if we are at the end
reader.Read();
}
return value;
}
public override bool CanWrite
{
get { return false; }
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
Now obviously there's a lot more you would want to do to get this really robust, but this gives you the basics of how to do it. There are more lightweight alternatives if you simply need to change property names (either JsonPropertyAttribute or overriding DefaultContractResolver.ResolvePropertyName(), but this gives you full control.