property names are different from original Object in the silverlight - silverlight

Following is part of service layer which is provided by WCF service :
[Serializable]
public class WaitInfo
{
private string roomName;
private string pName;
private string tagNo;
public string RoomName
{ get { return roomName; } set { this.roomName = value; } }
public string PName
{ get { return pName; } set { this.pName = value; } }
public string TagNo
{ get { return tagNo; } set { this.tagNo = value; } }
}
public class Service1 : IService1
{
public List<WaitInfo> GetWaitingList()
{
MyDBDataContext db = new MyDBDataContext();
var query = from w in db.WAIT_INFOs
select new WaitInfo
{
TagNo = w.PATIENT_INFO.TAG_NO,
RoomName= w.ROOM_INFO.ROOM_NAME,
PName= w.PATIENT_INFO.P_NAME
};
List<WaitInfo> result = query.ToList();
return result;
}
And following is codebehind part of UI layer which is provided by Silverlight
public MainPage()
{
InitializeComponent();
Service1Client s = new Service1Client();
s.GetWaitingListCompleted +=
new EventHandler<GetWaitingListByCompletedEventArgs>( s_GetWaitingListCompleted);
s.GetWaitingListAsync();
}
void s_GetWaitingListCompleted(object sender,
RadControlsSilverlightApplication1.ServiceReference2.GetWaitingListByCompletedEventArgs e)
{
GridDataGrid.ItemsSource = e.Result;
}
And following is xaml code in Silverlight page
<Grid x:Name="LayoutRoot">
<data:DataGrid x:Name="GridDataGrid"></data:DataGrid>
</Grid>
It is very simple code, however what I am thinking weird is property name of object at "e.Result" in the code behind page.
In the service layer, although properties' names are surely "RoomName, PName, TagNo", in the silverlight properties' names are "roomName, pName, tagNo" which are private variable name of the WaitingList Object.
Did I something wrong?
Thanks in advance.

Unless you specifically decorate your class with the DataContract attribute (which you should, instead of Serializable) then a default DataContract will be inferred. For normal Serializable types, this means the fields will be serialized as opposed to the properties.
You can markup your class in either of the following two ways. The latter will use the property accessors when serializing/deserializing your object which may be very useful or be a hassle depending on your circumstances.
[DataContract]
public class WaitInfo
{
[DataMember(Name="RoomName")]
private string roomName;
[DataMember(Name="PName")]
private string pName;
[DataMember(Name="TagNo")]
private string tagNo;
public string RoomName
{ get { return roomName; } set { this.roomName = value; } }
public string PName
{ get { return pName; } set { this.pName = value; } }
public string TagNo
{ get { return tagNo; } set { this.tagNo = value; } }
}
The method I prefer:
[DataContract]
public class WaitInfo
{
private string roomName;
private string pName;
private string tagNo;
[DataMember]
public string RoomName
{ get { return roomName; } set { this.roomName = value; } }
[DataMember]
public string PName
{ get { return pName; } set { this.pName = value; } }
[DataMember]
public string TagNo
{ get { return tagNo; } set { this.tagNo = value; } }
}

Related

How to add sublist in wpf using mvvm?

namespace colourchanges
{
public class Group
{
public string Name { get; set; }
//its a class for adding parent list using group class
}
public class EmployeeTree : INotifyPropertyChanged
{
public EmployeeTree()
{
this.GroupStaff = new List<Group>();
GroupStaff.Add(new Group { Name = "Designers" });
GroupStaff.Add(new Group { Name = "Developers" });
GroupStaff.Add(new Group { Name = "Managers" });
//here we are declaring list for adding parent list
}
private List<Group> _GroupStaff;
public List<Group> GroupStaff
{
get { return _GroupStaff; }
set
{
_GroupStaff = value;
RaisePropertyChanged("GroupStaff");
}
}
//creates a list for parentlist
private Group _selectedGroupStaff;
public Group selectedGroupStaff
{
get { return _selectedGroupStaff; }
set
{
_selectedGroupStaff = value;
if (selectedGroupStaff.Name == "Designers")
{
City = "Chennai";
Country = "India";
Email = "Designer#gmail.com";
MobileNo = 9094117917;
Address = "Annanagar";
}
else if (selectedGroupStaff.Name == "Developers")
{
City = "Trichy";
Country = "India";
Email = "Developer#gmail.com";
MobileNo = 9094667878;
Address = "Koyambedu";
}
else if (selectedGroupStaff.Name == "Managers")
{
City = "Salem";
Country = "India";
Email = "Manager#gmail.com";
MobileNo = 9094154678;
Address = "Arumbakkam";
}
RaisePropertyChanged("selectedGroupStaff");
}
}//for selecting parent list in order to bind to textbox
private string _City;
private string _Country;
private string _Email;
private long _MobileNo;
private string _Address;
//properties of parent list to bind to textbox
public string City
{
get { return _City; }
set
{
_City = value;
RaisePropertyChanged("City");
}
}
public string Country
{
get { return _Country; }
set
{
_Country = value;
RaisePropertyChanged("Country");
}
}
public string Email
{
get { return _Email; }
set
{
_Email = value;
RaisePropertyChanged("Email");
}
}
public long MobileNo
{
get { return _MobileNo; }
set
{
_MobileNo = value;
RaisePropertyChanged("MobileNo");
}
}
public string Address
{
get { return _Address; }
set
{
_Address = value;
RaisePropertyChanged("Address");
}
}
///raise property changed event handler code
public event PropertyChangedEventHandler PropertyChanged;
public void RaisePropertyChanged(string propertyName)
{
if (this.PropertyChanged != null)
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
//how to add sub list for designers developers and managers in the constructor
Let the following be your Model class
public class Group
{
private string _City;
private string _Country;
private string _Email;
private long _MobileNo;
private string _Address;
public Group()
{
Items = new ObservableCollection<Group>();
}
public ObservableCollection<Group> Items { get; set; }
}
and at the ViewModel's constructor, you can add the Items.
public EmployeeTree()
{
this.GroupStaff = new List<Group>();
Group rootGroup = new Group(){Name ="Manager"};
Group childGroup = new Group(){Name = "Developer"};
rootGroup.Items.Add(childGroup);
this.GroupStaff.Add(rootGroup);
}
This is for Hierarchical structure. Hope you are looking for this.
And your XAML should be like this
<TreeView Name="GroupTreeView">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Items}">
<TextBlock Text="{Binding Name}" />
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>

DisplayMemberPath databinding

I have a puzzled problem of databinding in WPF.
There is a listbox in XAML which it has linked with ItemSource,
but when it runs, it shows the lists of class names.
so I have applied to DisplayMemberPath, but it doesn't helpful.
and also I'm wondering how I can access inside class from generic class.
Thanks.
result
puzzled.Member
puzzled.Member
puzzled.Member
puzzled.Member
<DockPanel>
<ListBox Name="lbxMbrList" DockPanel.Dock="Left" Width="200" Padding="10"></ListBox>
<ContentControl />
</DockPanel>
private void Window_Loaded(object sender, RoutedEventArgs e)
{
members.Add(new Member("superman", "123-1234567", "address1"));
members.Add(new Member("batman", "111-111111", "address2"));
members.Add(new Member("goodman", "222-222222", "address3"));
members.Add(new Member("badman", "333-333333", "address4"));
lbxMbrList.ItemsSource = members;
lbxMbrList.DisplayMemberPath = members.MemberDetails; //<<it won't helpful
//var i = members.member.Name; //<<how can I access inside class?
//if (i == "superman")
//{
// MessageBox.Show("superman");
//}
}
public class Member
{
private string _name;
private string _phone;
private string _address;
public string Name { get { return _name; } set { _name = value; } }
public string Phone { get { return _phone; } set { _phone = value; } }
public string Address { get { return _address; } set { _address = value; } }
public Member() { }
public Member(string name, string phone, string address)
{
_name = name; _phone = phone; _address = address;
}
public string lbxMember
{
get { return string.Format("{0} - {1}", Name, Phone, Address); }
}
}
class MemberList : IEnumerable<Member>
{
private ObservableCollection<Member> memberList = new ObservableCollection<Member>();
public Member this[int i]
{
get {return memberList[i];}
set {memberList[i] = value;}
}
public void Add(Member member)
{
memberList.Add(member);
}
public void Remove(Member member)
{
memberList.Remove(member);
}
public IEnumerator<Member> GetEnumerator()
{
return memberList.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); }
public Member member { get; set; } //<< it think I has misunderstood it
public string MemberDetails
{
get
{ return string.Format("{0} - {1}", member.Name, member.Phone, member.Address); }
}
}
You are assigning the output of your MemberDetails property to the DisplayMemberPath. Instead, you need to assign the name of the property as a string.
lbxMbrList.DisplayMemberPath = "MemberDetails";
For what its worth, this will be easier to work with if you use an ItemTemplate in the ListBox.
[Edit]
Also, as #Blam mentions in his answer, your MemberDetails property is defined in the wrong class, it needs be in the Member class.
lbxMbrList.DisplayMemberPath = "lbxMember";
or
lbxMbrList.DisplayMemberPath = "MemberDetails";
And MemberDetails need to be a property of Member (not MemberList)

Map a Uri field using Dapper

What is the cleanest way to map a string column to a Uri property using Dapper?
Here's the cleanest I've been able to come up with so far (using the ITypeMap functionality):
Query:
SELECT * FROM TableWithAStringAddressColumn
POCO:
public class MyPoco
{
[ColumnSetter("DapperAddress")]
public Uri Address { get; set; }
private string DapperAddress { set { this.Address = new Uri(value); } }
}
Extensions:
partial class SqlMapper
{
public static void InitializeTypeMaps()
{
SqlMapper.SetTypeMap(
typeof(MyPoco),
new CustomPropertyTypeMap(typeof(MyPoco), SqlMapper.CustomSetterMapper));
// call out every other class that needs this kind of mapping
}
public static Func<Type, string, PropertyInfo> CustomSetterMapper =
(type, columnName) =>
{
PropertyInfo prop = type
.GetProperties()
.FirstOrDefault(p => string.Equals(columnName, p.Name, StringComparison.OrdinalIgnoreCase));
if (prop != null)
{
// find out if we need to use a different setter
ColumnSetterAttribute setterAttribute = prop.GetCustomAttributes(false).OfType<ColumnSetterAttribute>().LastOrDefault();
if (setterAttribute != null)
{
PropertyInfo setterProp = type
.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
.FirstOrDefault(p => string.Equals(setterAttribute.Setter, p.Name, StringComparison.OrdinalIgnoreCase));
if (setterProp == null)
{
throw new InvalidOperationException(string.Format("Setter property misconfigured (Property={0}, Setter={1})", prop.Name, setterAttribute.Setter));
}
else
{
prop = setterProp;
}
}
}
return prop;
};
}
Custom Attribute:
public class ColumnSetterAttribute : Attribute
{
public string Setter { get; set; }
public ColumnSetterAttribute(string setter)
{
this.Setter = setter;
}
}
[edit] I'm looking for a solution I can use without needing to call out all columns in all my queries (I'd like to find a solution where I can use SELECT *).
Seems like a lot of work...
Wouldn't this be ok?
public class MyPoco
{
private string _uriMapper;
public Uri SomeUri
{
get { return new Uri(_uriMapper); }
}
public string Mapper { set { _uriMapper = value; } }
}
Edit:
public class UriContainer
{
private string _uriMapper;
public string UriMapper { set { _uriMapper = value; } }
public int Id { get; set; }
public Uri SomeUri { get {return new Uri(_uriMapper);} }
}
public class DbTests
{
[Test]
public void Can_Get_A_Uri()
{
using (var c = new SqlConnection("hello"))
{
c.Open();
var uri = c.Query<UriContainer>("select *, someuri as urimapper from uris where id = 3").Single();
Console.WriteLine(uri.SomeUri);
}
}
}

MVVM and DBContext - how to put it together?

I'm trying to follow the MVVM pattern, however I spent some good time on this issue, googled a lot and checked stackoverflow as well... No working example found so far.
Basically, I've a simple application and want to retrieve and write data to SQL server. Here's my code:
//Model
public class Visitor
{
public string ID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
//ViewModel
public class VisitorViewModel : ViewModelBase
{
public ObservableCollection<Visitor> _visitorDataCollection = new ObservableCollection<Visitor>();
public ObservableCollection<Visitor> VisitorDataCollection
{
get { return _visitorDataCollection; }
set { _visitorDataCollection = value; }
}
private string _firstName = "";
private string _lastName = "";
public string FirstName
{
get { return _firstName; }
set
{
if (value != _firstName)
{
_firstName = value;
OnPropertyChanged("FirstName");
}
}
}
public string LastName
{
get { return _lastName; }
set
{
if (value != _lastName)
{
_lastName = value;
OnPropertyChanged("LastName");
}
}
}
public VisitorViewModel()
{
}
}
}
//VisitorContext class that represents a database context
public partial class VisitorContext : DbContext
{
public VisitorContext()
: base()
{
}
public DbSet<VISITOR> Visitors { get; set; }
}
}
Nothing really fancy. However, I cannot put it "together". How to complete that to retrieve all visitors and add a new one?
Could someone point me to the right direction?
Just a simple example how make it all to life.
Add some commands to VM:
public ICommand Add {get; private set;}
In constructor:
public VisitorViewModel()
{
using(var context = new VisitorContext())
{
//fill collection with initial data from DbContext
context.Visitors.ToList().ForEach(_visitorDataCollection.Add);
}
//setup add command, here I'm using MVVM Light like you
Add = new RelayCommand(()=> {
using(var context = new VisitorContext())
{
_visitorDataCollection.Add(context.Visitors.Add(new Visitor {
FirstName = this.FirstName,
LastName = this.LastName //read values from model properties
});
}
});
}
That's it, all you need to do is bind this ViewModel to appropriate View.

ReactiveUI and Validation

What's considered "best practice" when performing data validation while using ReactiveUI? Let's say I have a view model that looks like this:
public class MyViewModel: ReactiveObject
{
public ReactiveAsyncCommand SaveMyDataCommand { get; protected set; }
private string _email;
public string Email
{
get { return _email; }
set
{
_email = value;
raisePropertyChanged("Email");
}
}
private string _name;
public string Name
{
get { return _name; }
set
{
_name= value;
raisePropertyChanged("Name");
}
}
private bool _sendEmail = false;
public bool SendEmail
{
get { return _sendEmail; }
set
{
_sendEmail = value;
raisePropertyChanged("SendEmail");
}
}
public MyViewModel()
{
SaveMyDataCommand = new ReactiveAsyncCommand(null, 1);
}
}
Here's what I want to validate:
If SendEmail == true then make sure there's a valid email address in the Email property. (I'm not worried about the actual email address validation piece itself. This is just a what if scenario.)
If a value was set to the Email property, make sure it's a valid email address.
If either 1. or 2. fail validation, SaveMyDataCommand should not be executable.
I'm just looking for a good example on how to do simple / slightly more complex data validation using ReactiveUI. Can anyone shed some light on this?
For anyone else looking for an example on using ReactiveValidatedObject, here's what worked for me. Note that you'll have to add a reference to System.ComponentModel to your class as well.
public class MyViewModel: ReactiveValidatedObject
{
public ReactiveAsyncCommand SaveMyDataCommand { get; protected set; }
// THIS PROPERTY INDICATES WHETHER ALL FIELDS HAVE BEEN VALIDATED
public bool IsSaveEnabled
{
get { return IsObjectValid(); }
}
private string _email;
[ValidatesViaMethod(AllowBlanks=true,AllowNull=true,Name="IsEmailValid",ErrorMessage="Please enter a valid email address")]
public string Email
{
get { return _email; }
set
{
_email = value;
raisePropertyChanged("Email");
SendEmail = SendEmail;
raisePropertyChanged("IsSaveEnabled");
}
}
private string _name;
public string Name
{
get { return _name; }
set
{
_name= value;
raisePropertyChanged("Name");
}
}
private bool _sendEmail = false;
[ValidatesViaMethod(Name = "IsSendEmailValid", ErrorMessage = "Make sure a valid email address is entered.")]
public bool SendEmail
{
get { return _sendEmail; }
set
{
_sendEmail = value;
raisePropertyChanged("SendEmail");
raisePropertyChanged("IsSaveEnabled");
}
}
public bool IsEmailValid(string email)
{
if (string.IsNullOrEmpty(email))
{
return true;
}
// Return result of Email validation
}
public bool IsSendEmailValid(bool sendEmail)
{
if (sendEmail)
{
if (string.IsNullOrEmpty(Email))
{
return false;
}
// Return result of Email validation
}
}
public MyViewModel()
{
SaveMyDataCommand = new ReactiveAsyncCommand(null, 1);
}
}
I hope this helps someone! :)
Use ReactiveValidatedObject, then use Data Annotations (on phone, sorry for short message)

Resources