Silverlight databinding error - wpf

I found an example online that explains how to perform databinding to a ListBox control using LINQ in WPF. The example works fine but when I replicate the same code in Silverlight it doesn't work. Is there a fundamental difference between Silverlight and WPF that I'm not aware of?
Here is an Example of the XAML:
<ListBox x:Name="listBox1">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Name}" FontSize="18"/>
<TextBlock Text="{Binding Role}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Here is an example of my code behind:
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
string[] names = new string[] { "Captain Avatar", "Derek Wildstar", "Queen Starsha" };
string[] roles = new string[] { "Hero", "Captain", "Queen of Iscandar" };
listBox1.ItemSource = from n in names from r in roles select new { Name = n, Role = r}
}

Silverlight does not support binding to anonymous types. (To be technically correct, Silverlight does not support reflecting against internal types, and since anonymous types are internal, this doesn't work). See this article for a simple workaround- you will merely need to create a model class to hold the data.
public class MyItem
{
public string Name { get; set; }
public string Role { get; set; }
}
listBox1.ItemSource = from n in names from r in roles select new MyItem() { Name = n, Role = r}

In Silverlight you can not bind to anonymous types. Silverlight requires the type of the item being bound to be public but anonymous types are by internal.
You will need to to create a public type to carry your results:-
public class MyItem
{
public string Name {get; set; }
public string Role {get; set; }
}
now in your code:-
listBox1.ItemSource = from n in names from r in roles select new MyItem() { Name = n, Role = r}

Related

Using ComboBox to set value of field from a source List<T> with two values - WPF

I need a combobox to list the items from a List with two fields :
AcctTypeID - This is an int (0 - 20).
AcctTypeName - This is a string -- ex. "Accounts Payable" (the cooresponding AcctTypeID is say 10 for Accounts Payable).
I need the ComboBox to show the AcctTypeName but send the AcctTypeID to the underlying field.
I promise I have spent hours seraching for this and trying every idea I can think of or find.
Use this XAML and set or bind the ItemsSource of the ComboBox to an IEnumerable<T> where T is your class with the AcctTypeName and AcctTypeID properties:
<ComboBox x:Name="cmb" DisplayMemberPath="AcctTypeName" SelectedValuePath="AcctTypeID" />
You get the selected value using the SelectedValue property:
int acctTypeID = (int)cmb.SelectedValue;
It is impossible to give an exact answer to your question without some additional explanations.
For example, if you are using MVVM, then your code should be implemented like this:
public class AcctTypeDto
{
public int AcctTypeId { get; set; }
public string AcctTypeName { get; set; }
}
public class AcctTypesViewModel
{
public ObservableCollection<AcctTypeDto> AcctTypes { get; }
= new ObservableCollection<AcctTypeDto>()
{
new AcctTypeDto(){AcctTypeId=123, AcctTypeName="Teen"},
new AcctTypeDto(){AcctTypeId=456, AcctTypeName="Five"},
new AcctTypeDto(){AcctTypeId=789, AcctTypeName="Seven"}
};
private RelayCommand _sendIdCommand;
public RelayCommand SendIdCommand => _sendIdCommand
?? (_sendIdCommand = new RelayCommand<int>(SendIdExecute));
private static void SendIdExecute(int parameter)
{
MessageBox.Show($"Id={parameter}");
}
private RelayCommand _sendAccCommand;
public RelayCommand SendAccCommand => _sendAccCommand
?? (_sendAccCommand = new RelayCommand<AcctTypeDto>(SendAccExecute));
private static void SendAccExecute(AcctTypeDto parameter)
{
MessageBox.Show($"Id={parameter.AcctTypeId}; Name={parameter.AcctTypeName}");
}
}
<FrameworkElement.DataContext>
<local:AcctTypesViewModel/>
</FrameworkElement.DataContext>
<UniformGrid Columns="1">
<ComboBox x:Name="comboBox" VerticalAlignment="Top" ItemsSource="{Binding AcctTypes}"
DisplayMemberPath="AcctTypeName"
SelectedValuePath="AcctTypeId"/>
<Button Content="Send Id" VerticalAlignment="Center"
Command="{Binding SendIdCommand}"
CommandParameter="{Binding SelectedValue, ElementName=comboBox}"/>
<Button Content="Send AcctType" VerticalAlignment="Center"
Command="{Binding SendAccCommand}"
CommandParameter="{Binding SelectedItem, ElementName=comboBox}"/>
</UniformGrid>
RelayCommand and RelayCommand<T> classes used.

How to create a generic view model

I have to create a generic viewmodel passing an entity with a one to many relationship.
I'll explain:
My WIndows:
<Window x:Class="Invoice_Example_Brux.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:invoiceExampleBrux="clr-namespace:Invoice_Example_Brux"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<invoiceExampleBrux:MainWindowViewModel/>
</Window.DataContext>
<Grid>
<TextBox HorizontalAlignment="Left" Height="23" Margin="174,78,0,0" TextWrapping="Wrap" Text="{Binding MyModel.Name}" VerticalAlignment="Top" Width="120"/>
<Label Content="Id" HorizontalAlignment="Left" Margin="10,53,0,0" VerticalAlignment="Top"/>
<TextBox HorizontalAlignment="Left" Height="23" Margin="10,78,0,0" TextWrapping="Wrap" Text="{Binding MyModel.Id}" VerticalAlignment="Top" Width="120" IsReadOnly="True"/>
<Label Content="Number" HorizontalAlignment="Left" Margin="322,52,0,0" VerticalAlignment="Top"/>
<TextBox HorizontalAlignment="Left" Height="23" Margin="322,78,0,0" TextWrapping="Wrap" Text="{Binding MyModel.Number}" VerticalAlignment="Top" Width="120"/>
<Label Content="Name" HorizontalAlignment="Left" Margin="174,53,0,0" VerticalAlignment="Top"/>
<Button Content="Save" HorizontalAlignment="Left" Margin="211,288,0,0" VerticalAlignment="Top" Width="75" Command="{Binding SaveCommand}"/>
<ComboBox
SelectionChanged="Selector_OnSelectionChanged"
HorizontalAlignment="Left" Margin="180,38,0,0" VerticalAlignment="Top" Width="120"
DisplayMemberPath="Name"
ItemsSource="{Binding DocumentType,UpdateSourceTrigger=PropertyChanged}"/>
<Label Content="Type Document" HorizontalAlignment="Left" Margin="192,12,0,0" VerticalAlignment="Top"/>
</Grid>
myWindows codebheind:
namespace Invoice_Example_Brux
{
public partial class MainWindow
{
public MainWindow()
{
InitializeComponent();
}
private void Selector_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
var cmb = sender as ComboBox;
var selectedItem = cmb.SelectedValue as DocumentType;
if (selectedItem == null) return;
var code = selectedItem.Code;
switch (code)
{
case "A":
DataContext = new ViewModelGeneric<DocumentA>();
break;
case "B":
DataContext = new ViewModelGeneric<DocumentB>();
break;
case "C":
break;
}
}
}
}
My Entity DocumentA and DocumentB:
public class DocumentA : DocumentGeneral
{
public ObservableCollection<DetailDocumentA> DetailDocumentA { get; set; }
}
public class DetailDocumentA : DetailDocumentGeneral
{
}
public class DocumentB : DocumentGeneral
{
public ObservableCollection<DetailDocumentB> DetailDocumentB { get; set; }
}
public class DetailDocumentB : DetailDocumentGeneral
{
}
public class DocumentGeneral
{
public Guid Id { get; set; }
public string Name { get; set; }
public string Number { get; set; }
public string TypeDocument { get; set; }
}
public class DetailDocumentGeneral
{
public Guid Id { get; set; }
public string Quantity { get; set; }
public string Price { get; set; }
public string Total { get; set; }
}
My ViewModelGeneric:
public class ViewModelGeneric<T> : ViewModelBase
where T : DocumentGeneral, new()
{
public T MyModel { get; set; }
public RelayCommand SaveCommand { get; set; }
public ViewModelGeneric()
{
MyModel = new T();
SaveCommand = new RelayCommand(Save);
}
private void Save(object obj)
{
if (MyModel.Id == Guid.Empty)
{
MyModel.Id = Guid.NewGuid();
}
//the problme is here. how can I do to fill in the detail of my entity
/* MyModel.Detail.Add(new DetailDocumentGeneral
{
Price = "50",Quantity = "100",Total = "5000"
});*/
using (var ctx = new DocumentContext())
{
var document = ctx.Set<T>();
document.Add(MyModel);
ctx.SaveChanges();
}
}
}
the problem is that depending on the choice of my combobox I have to go a different entity.
But I can not access the respective detailDocument = (
Please stop what you are doing... WPF is a verbose language. That means that you'll have to write loads of code, probably even duplicating large sections. Please just do yourself a favour and accept this fact. I've seen this situation time and time again (and even wasted my own time on it when I was first learning WPF), but it always ends in tears.
In MVVM, it is customary to provide one view model for one view. This view model is responsible for providing all of the data and functionality for the related view. Unless all of your views are almost identical, then your generic view model simply won't work. Worse still, even if it did work, it would complicate the hell out of your project and make simple tasks more difficult.
If you really don't want to rewrite your view models each time, then just copy and paste from another view model and just change the differences. Having said all that, I must say that your code seems to be somewhat at odd with your words... you say that you want a generic view model, but your problems relates to data access.
It is far more usual to have your data access class(es) in a separate project to your view models. In this respect, it seems as though you are trying to implement The Repository Pattern, but in the wrong place. Making generic data access classes is far more common and has far less to go wrong than a generic view model.
Therefore, I would strongly recommend that you forget about generic view models and declare a new one for each view and then move your data access code into a separate project (or at least a separate class) and optionally make that generic instead (using the linked page on MSDN for help). This may be the first real problem that you have come across in this endeavour, but if you continue along this path, I can guarantee you that it won't be the last.

ListBox DataTemplate for dynamically loaded type

I have a sample MVVM WPF application and I'm having problems creating DataTemplates for my dynamically loaded model. Let me try explain:
I have the following simplified classes as part of my Model, which I'm loading dynamically
public class Relationship
{
public string Category { get; set; }
public ParticipantsType Participants { get; set; }
}
public class ParticipantsType
{
public ObservableCollection<ParticipantType> Participant { get; set; }
}
public class ParticipantType
{
}
public class EmployeeParticipant : ParticipantType
{
public EmployeeIdentityType Employee { get; set; }
}
public class DepartmentParticipant : ParticipantType
{
public DepartmentIdentityType Department { get; set; }
}
public class EmployeeIdentityType
{
public string ID { get; set; }
}
public class DepartmentIdentityType
{
public string ID { get; set; }
}
Here is how my View Model looks like. I created a generic object Model property to expose my Model:
public class MainViewModel : ViewModelBase<MainViewModel>
{
public MainViewModel()
{
SetMockModel();
}
private void SetMockModel()
{
Relationship rel = new Relationship();
rel.Category = "213";
EmployeeParticipant emp = new EmployeeParticipant();
emp.Employee = new EmployeeIdentityType();
emp.Employee.ID = "222";
DepartmentParticipant dep = new DepartmentParticipant();
dep.Department = new DepartmentIdentityType();
dep.Department.ID = "444";
rel.Participants = new ParticipantsType() { Participant = new ObservableCollection<ParticipantType>() };
rel.Participants.Participant.Add(emp);
rel.Participants.Participant.Add(dep);
Model = rel;
}
private object _Model;
public object Model
{
get { return _Model; }
set
{
_Model = value;
NotifyPropertyChanged(m => m.Model);
}
}
}
Then I tried creating a ListBox to display specifically the Participants Collection:
<ListBox ItemsSource="{Binding Path=Model.Participants.Participant}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<Expander Header="IdentityFields">
<!-- WHAT TO PUT HERE IF PARTICIPANTS HAVE DIFFERENT PROPERTY NAMES -->
</Expander>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
The problem is:
I don't know how to create a template that can handle both type of ParticipantTypes, in this case I could have EmployeeParticipant or DepartmentParticipant so depending on that, the data binding Path would be set to Employee or Department properties accordingly
I though about creating a DataTemplate for each type (e.g. x:Type EmployeeParticipant) but the problem is that my classes in my model are loaded dynamically at runtime so VisualStudio will complain that those types don't exist in the current solution.
How could I represent this data in a ListBox then if my concrete types are not known at compile time, but only at runtime?
EDIT: Added my test ViewModel class
You can still create a DataTemplate for each type but instead of using DataType declarations to have them automatically resolve you can create a DataTemplateSelector with a property for each template (assigned from StaticResource in XAML) that can cast the incoming data item to the base class and check properties or otherwise determine which template to use at runtime. Assign that selector to ListBox.ItemTemplateSelector and you'll get similar behavior to what DataType would give you.
That's not a good view-model. Your view-model should be view-centric, not business-centric. So make a class that can handle all four cases from a visual perspective, then bridge your business classes over to that view-model.
EDIT:
Working off your code:
<ListBox ItemsSource="{Binding Path=Model.Participants}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<Expander Header="IdentityFields">
<TextBlock Text={Binding Id} />
<TextBlock Text={Binding Name} />
</Expander>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
I changed the binding, I assume that was a mistake?
I would create a ViewModel for Participant:
public class Participant_VM : ViewModelBase
{
private string _name = string.Empty;
public string Name
{
get
{
return _name ;
}
set
{
if (_name == value)
{
return;
}
_name = value;
RaisePropertyChanged(() => Name);
}
private string _id= string.Empty;
public string Id
{
get
{
return _id;
}
set
{
if (_id== value)
{
return;
}
_id = value;
RaisePropertyChanged(() => Id);
}
}
}
Modify the ListBox as follows.
<ListBox ItemsSource="{Binding Model.Participants.Participant}">
<ListBox.Resources>
<DataTemplate DataType="{x:Type loc:DepartmentParticipant}">
<Grid>
<TextBlock Text="{Binding Department.ID}"/>
</Grid>
</DataTemplate>
<DataTemplate DataType="{x:Type loc:EmployeeParticipant}">
<Grid>
<TextBlock Text="{Binding Employee.ID}"/>
</Grid>
</DataTemplate>
</ListBox.Resources>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<Expander Header="IdentityFields">
<!-- WHAT TO PUT HERE IF PARTICIPANTS HAVE DIFFERENT PROPERTY NAMES -->
<ContentPresenter Content="{Binding }"/>
</Expander>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Edit:
loc refers to the namespace in which the DepartmentParticipant and EmployeeParticipant are present. Hope you are familiar with adding namespaces.

Binding to Complex Objects in the ViewModel from the View?

Say for example I have the following type:
public class Site
{
public string Name { get; set; }
public int SiteId { get; set; }
public bool IsLocal { get; set; }
}
The above type can be assigned to be held in a Propety in a ViewModel like so assuming a corresponding backing field has been created but omitted here ofc:
public Site SelectedSite
{
get { return _selectedSite; }
set
{
_selectedSite = value;
// raise property changed etc
}
}
In my xaml a straight forward binding would be:
<TextBlock x:Name="StatusMessageTextBlock"
Width="Auto"
Height="Auto"
Style="{StaticResource StatusMessageboxTextStyle}"
Text="{Binding MessageToDisplay,
Mode=OneWay,
UpdateSourceTrigger=PropertyChanged}" />
Can you extend a binding by using the dot notation syntax? e.g:
<TextBlock x:Name="StatusMessageTextBlock"
Width="Auto"
Height="Auto"
Style="{StaticResource StatusMessageboxTextStyle}"
**Text="{Binding SelectedSite.Name,**
Mode=OneWay,
UpdateSourceTrigger=PropertyChanged}" />
Seems like a an interesting feature but my gut instinct is a no as my DC is being assigned at RunTime so at DesignTime or CompileTime, I can't see any clues that could make this feature work or not?
Correct me if have misunderstood what a complex object is, I have simplified mine down for the sake of this question.
Of course this is possible. However, WPF needs to know when any property along the path has changed. To that end, you need to implement INotifyPropertyChanged (or other supported mechanisms). In your example, both Site and the VM containing SelectedSite should implement change notification).
Here's how you could implement the functionality you specified in your question:
// simple DTO
public class Site
{
public string Name { get; set; }
public int SiteId { get; set; }
public bool IsLocal { get; set; }
}
// base class for view models
public abstract class ViewModel
{
// see http://kentb.blogspot.co.uk/2009/04/mvvm-infrastructure-viewmodel.html for an example
}
public class SiteViewModel : ViewModel
{
private readonly Site site;
public SiteViewModel(Site site)
{
this.site = site;
}
// this is what your view binds to
public string Name
{
get { return this.site.Name; }
set
{
if (this.site.Name != value)
{
this.site.Name = value;
this.OnPropertyChanged(() => this.Name);
}
}
}
// other properties
}
public class SitesViewModel : ViewModel
{
private readonly ICollection<SiteViewModel> sites;
private SiteViewModel selectedSite;
public SitesViewModel()
{
this.sites = ...;
}
public ICollection<SiteViewModel> Sites
{
get { return this.sites; }
}
public SiteViewModel SelectedSite
{
get { return this.selectedSite; }
set
{
if (this.selectedSite != value)
{
this.selectedSite = value;
this.OnPropertyChanged(() => this.SelectedSite);
}
}
}
}
And your view might look something like this (assuming a DataContext of type SitesViewModel):
<ListBox ItemsSource="{Binding Sites}" SelectedItem="{Binding SelectedSite}"/>
Below is what worked for me:
public Site SelectedSite
{
get { return _selectedSite; }
set
{
_selectedSite = value;
RaisePropertyChanged("SelectedSite");
}
}
In my xaml I was able to do:
<TextBox Name="tbSiteName"
Width="250"
Height="30"
Margin="0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
IsReadOnly="True"
Style="{StaticResource MainTextBoxStyle}"
Text="{Binding SelectedSite.Name,
Mode=OneWay,
UpdateSourceTrigger=PropertyChanged}" />
This allows you to access data members off the Site Type without having to create individual properties that wrap each data member on the Site Type. Then individual controls can bind to each property declared in the VM. In a one to one fashion, this aproach can become rather verbose. The binding extension attached to the Text property of the TextBox control shown above, shows that we are not binding to a simple straight forward property but actually to a custom type. Potentially removing the need to create more public properties.

WPF Data binding issue using mvvm pattern

I have created a user control "SearchControl"(which will be reused further in other screens as well.
SearchControl ->
<usercontrol name="SearchControl"......>
<stackpanel orientation="horizontal"...>
<TextBox Text"{Binding Path=UserId}"...>
<Button Content="_Search" ....Command="{Binding Path=SearchCommand}"..>
</stackpanel>
</usercontrol>
public partial class SearchControl : UserControl
{
public SearchControl()
{
InitializeComponent();
DataContext=new UserViewModel();
}
}
I then use this control in a window "UserSearch"
<window name="UserSearch".............
xmlns:Views="Namespace.....Views">
<Grid>
<Grid.RowDefinitions>
<RowDefinition..../>
<RowDefinition..../>
<RowDefinition..../>
<RowDefinition..../>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition..../>
<ColumnDefinition..../>
</Grid.ColumnDefinitions>
<Views:SearchControl Grid.Row="0" Grid.Colspan="2"/>
<TextBlock Text="User Id" Grid.Row="1" Grid.Column="0"..../>
<TextBox Text="{Binding Path=UserId}" Grid.Row="1" Grid.Column="1".../>
<TextBlock Text="First Name" Grid.Row="2" Grid.Column="0"..../>
<TextBox Text="{Binding Path=FirstName}" Grid.Row="2" Grid.Column="1".../>
<TextBlock Text="Last Name" Grid.Row="3" Grid.Column="0"..../>
<TextBox Text="{Binding Path=LastName}" Grid.Row="3" Grid.Column="1".../>
</Grid>
</window>
public partial class UserSearch : Window
{
public UserSearch()
{
InitializeComponent();
DataContext=new UserViewModel();
}
}
What I am aimimg for:
When I enter UserId inthe textbox in SearchControl and click on Search button, the resulting record which is retieved should be displayed in the textboxes for UserId, FirstName, LastName
class UserViewModel:INotifyPropertyChanged
{
DBEntities _ent; //ADO.Net Entity set
RelayCommand _searchCommand;
public UserViewModel()
{
_ent = new DBEntities();
}
public string UserId {get; set;}
public string FirstName {get; set;}
public string LastName {get; set;}
public ICommand SearchCommand
{
get
{
if(_searchCommand == null)
{
_searchCommand = new RelayCommand(param = > this.Search());
}
return _searchCommand;
}
}
public void Search()
{
User usr = (from u in _ent
where u.UserId = UserId
select u).FirstOrDefault<User>();
UserId = usr.UserId;
FirstName = usr.FirstName;
LastName = usr.LastName;
OnPropertyChanged("UserId");
OnPropertyChanged("FirstName");
OnPropertyChanged("LastName");
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
if(PropertyChanged != null)
PropertyChanged(this, new PropertChangedEventArgs(propertyName);
}
}
Here as I am using two separate instances of the UserViewModel for the SearchControl and UserSearch, even though I retieve the record for the particular user on searching by UserId, I am unable to bind the properties UserId, FullName , LastName with the respective textboxes...How do I fix this problem??
1) Don't let the View initialize the presentation model, it should be the other way round. The presentation model is the object of interest, not the particular view.
public interface IView
{
void SetModel(IPresentationModel model);
}
publiv class View : UserControl, IView
{
public void SetModel(IPresentationModel model)
{
DataContext = model;
}
}
public class PresentationModel : IPresentationModel
{
public PresentationModel(IView view)
{
view.SetModel(this);
}
}
2) Don't set the data context of the subview in the code behind file. Usually, the view that uses the subview sets the data context in the xaml file.
3) Usually each view has its own presentation model. The presentation model should have one type of view. That means that different views of a single presentation model may differ in appearance but not in functionality (in your case one view is used to search, the other one is used to display and edit data). So, you have vialoted the Single Responsibilty Principle.
4) Abstract your data access layer, otherwise you won't be able to unit test your presentation model (because it needs access to the data base directly). Define an repository interface and implementation:
public interface IUserRepository
{
User GetById(int id);
}
public class EntityFrameworkUserRepository : IUserRepository
{
private readonly DBEntities _entities;
public EntityFrameworkUserRepository(DBEntities entities)
{
_entities = entities;
}
public User GetById(int id)
{
return _entities.SingleOrDefault(u => u.UserId == id);
}
}
5) Don't use FirstOrDefault because an ID is unique, so there must not be several users for one id. SingleOrDefault (used in the code snippet above) throws an exception if more than one result is found but returns null if none is found.
6) Bind directly to your entity:
public interface IPresentationModel
{
User User { get; }
}
<StackPanel DataContext="{Binding Path=User}">
<TextBox Text="{Binding Path=FirstName}" />
<TextBox Text="{Binding Path=LastName}" />
</StackPanel>
7) Use the CommandParameter to provide the user id you are searching for directly with your command.
<TextBox x:Name="UserIdTextBox">
<Button Content="Search" Command="{Binding Path=SearchCommand}"
CommandParameter="{Binding ElementName=UserIdTextBox, Path=Text}" />
public class PresentationModel
{
public ICommand SearchCommand
{
// DelegateCommand<> is implemented in some of Microsoft.BestPractices
// assemblies, but you can easily implement it yourself.
get { return new DelegateCommand<int>(Search); }
}
private void Search(int userId)
{
_userRepository.GetById(userId);
}
}
8) If only data binding causes issues, look at the following website to get some ideas how to debug wpf data bindings: http://beacosta.com/blog/?p=52
9) Don't use strings that contain property names. Once you refactor your code and properties change their names, to will have a stressful time finding all property names in strings and fixing them. Use lambda expressions instead:
public class PresentationModel : INotifiyPropertyChanged
{
private string _value;
public string Value
{
get { return _value; }
set
{
if (value == _value) return;
_value = value;
RaisePropertyChanged(x => x.Value);
}
}
public PropertyChangedEventHandler PropertyChanged;
public void RaisePropertyChanged(Expression<Func<PresentationModel, object>> expression)
{
if (PropertyChanged == null) return;
var memberName = ((MemberExpression)expression.Body).Member.Name;
PropertyChanged(this, new PropertyChangedEventArgs(memberName));
}
}
I wish you the best to solve your problem and I hope that I could help you a little bit.
Best Regards
Oliver Hanappi

Resources