WPF - Raise property changed for ToString - c#

Currently i have the problem, that my business object overrides ToString for delivering data to some telerik control (RadListBox/RadListBoxItem). The model which overrides ToString implements INotifyPropertyChanged. Is it possible in c# to raise the method ToString to be changed? The initial values get's displayed well, but later changes will be ignored. For example:
public class ViewModel : UI.MVC.ViewModelBase
{
private string name;
[JsonProperty]
public string Name
{
get
{
return name;
}
set
{
name = value;
RaisePropertyChanged("Name");
}
}
public override string ToString()
{
return name ?? "--";
}
}
For example if Name is chagned, ToString should be called to get the new value.
EDIT
The ViewModel from above is embedded in another viewmodel. which is binded to a RadPropertyGrid:
public class FirstViewModel : : UI.MVC.ViewModelBase
{
public FirstViewModel()
{
SelectedItem = new ViewModel();
}
public object SelectedItem
{
get;
}
}
An instance of RistViewModel is the datacontext of the containing window.
XAML
<telerik:RadPropertyGrid NestedPropertiesVisibility="Visible"
x:Name="propertyGrid" Grid.Column="1" Grid.Row="1" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" IsGrouped="True"
Item="{Binding SelectedItem,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" />
Thank you very much!

Is it possible in c# to raise the method ToString to be changed?
No, it is not possible. You cannot force other code to call ToString() again as a direct consequence of some other event. For that matter, the only reason INotifyPropertyChanged works is that, by convention, code knows to subscribe to that event and call a property getter (which is a type of method) when the event is raised. The event doesn't actually force any code to call the property getter; it's just that anyone who bothered to subscribe to the event is almost certainly going to call that method when the event is raised.
Of course, you can always set up whatever mechanism between consenting pieces of code you want. But for code that itself has no reason to believe that it might get a different result from ToString() depending on when it's called, such a mechanism won't exist.
For example if Name is chagned, ToString should be called to get the new value.
You can always subscribe to INotifyPropertyChanged.PropertyChanged yourself, and then do something to force the ToString() method to be called again. It is not clear from the little code you provided how this might be done; maybe setting SelectedItem to null and then back to the desired object.
All that said, while I'm not familiar with the control you are using (RadPropertyGrid), assuming it follows the normal WPF model, then if it is in fact displaying the SelectedItem object in some way, I would guess that it's doing so in a manner that would be compatible with the use of a DataTemplate for that type. I.e. if you were to declare a DataTemplate for the ViewModel class, you could bind directly to the Name property. For example:
<DataTemplate DataType="l:ViewModel">
<TextBlock Text="{Binding Name}"/>
</DataTemplate>
…and WPF would automatically update the displayed name if and when it changes.
Your ToString() method provides a default name value of "--". This could be incorporated into the Name property itself if you want, or you could add a new property, e.g. DisplayName that provides that (i.e. if for some reason you need Name to remain null when the property hasn't been set).
Without a good, minimal, complete code example that shows clearly what you're doing, it's impossible to know for sure what the best approach would be. But it would be surprising for a good WPF library to not support normal binding and templating mechanisms, and instead to rely completely on a ToString() override without any mechanism for value update notifications.

Related

inside the class do you assign the value to the property or the backing field

Suppose I have the following in a class (that extends MVVMLight's ViewModelBase):
private ObservableCollection<Merchant> merchants;
public ObservableCollection<Merchant> Merchants
{
get { return merchants; }
set { Set(nameof(Merchants), ref merchants, value); }
}
Inside my class, should I initialize the value of the property or the backing field? And in the methods of my class should I use the property or the backing field?
I am just learning and I tend to use both, and I don't see any difference.
Simply put: inside the class, should i use the property or its backing field?
It really depends on what you want to do.
When your property raises PropertyChanged it is a good idea to use the property setter instead of the backing field, even from within your class, so consumers get notified of the changed value.
There is one exception though: Inside your constructor, you would use the backing field, because at that time no consumer could possibly have subscribed to the PropertyChanged event, so raising the event from the constructor is not necessary.
If you have other logic in your setter - like validation - you always should use the property setter instead of the backing field.
I'd go with the property. This way when you add logic to the getter or setter (say, validation) you won't have to change anything else.
The whole idea of the get; set; is to grant a controlled level of access to the 'backing field' from classes that may, otherwise, not have visibility of it.
With that in mind, you can assume the get or set will, and quite often does, have it's own logic for when other classes are to access the backing field's value or set it in a particular way. You may or may not want this class (the class that owns the backing field) to invoke the custom getter/setter and there lies your answer as to what property you should refer to.
In case it is a property with both getter and setter, use the automatic property with the following syntax:
public ObservableCollection<Merchant> Merchants { get; set; }
In case you have to restrict the access to one of them, do it like in the following:
public ObservableCollection<Merchant> Merchants { get; private set; }
The only cause to use private backing field is either when it's readonly, and then you will initialize it in the constructor, or in case you have some additional logic on setting the property value (like, when implementing INotifyPropertyChanged).
Also, using the property access is much more refactoring-friendly.
Bottom line: use property setter, unless it is an immutable (readonly) field or you want to circumvent the property's setter logic.

Why use private property setters since member variables can be accessed directly?

In C#, we can do something like:
private string _myField;
public string MyProperty
{
get { return _myField; }
private set { _myField = value; }
}
What is the advantage of using a private setter in the property here while we can set _myField inside the class as we want? Why would we want to use the setter of MyProperty?
A setter can implement other behaviour/logic when a property is updated, so that you don't have to manually implement it at every location where a property might be updated.
It can:
automatically update other fields
Validate the new value (eg. ensure an email address matches a regular expression)
To keep code that needs to be run every time a field is updated in one place
For example:
private string _myField;
private int _myField_num_updated;
private DateTime _myField_updated_at;
public string MyProperty
{
get { return _myField; }
private set {
_myField = value;
_myField_num_updated++;
_myField_updated_at = DateTime.Now;
}
}
The goal of using property accessors (get and set) is to hide the internal implementation on how particular values are queried or modified. In your case, the setter is simple, but in the future, it might become more complicated. By hiding the implementation, you minimize the impact of potential changes and keep the interface simple.
Now concerning your question: why using a private setter? The reason for using a private setter is exactly the same as the reason for using a setter in general. In the case of a private setter, the user of that setter is the code of the class itself. In case of a public setter, the user could be anybody using the class. The advantage of using the setter remains the same.
Because while properties more often than not are wrapping backing fields, there is no reason that they must. Properties can also implement custom business logic (usually some kind of validation or conversion) and call other functions. Using a private setter makes your code more idiomatic (meaning others will more readily understand what you're doing) and more expressive (meaning the code will, or should, more closely reflect the semantics of what you are trying to accomplish. Private setters also allow this custom logic to be encapsulated, so that there's only one place that you need to change it in the event that logic changes or the code needs refactoring.
With a setter you can control the value when you try to set it, for example if you have an int that you want to be sure does not have a value greater than ten.
public int MyProp
{
get { return _my_prop;}
private set {
if value > 10 {
_my_prop = 10;
}
}
}
Property mainly serves for 2 purpose:
avoid unexpected access to the underlying field from outside
hide the implementation detail of the underlying field, so you can change the implementation freely as long as you keep the interface.
As to a private setting, while the first doesn't make much sense, the second item is still valid
need a private setter in a property is to use your field wrapped in property only for being modify directly by other function, properties of your class. So in one place (property) you set value of your field but all other elements of your class have not to access directly to your private field but through property that wrapped it.

Check if textbox is empty in a WPF form from another class C#

I have an WPF form with 3 textbox named FirstName LastName and GPA, and i want to check their content before inserting into the database. But i am trying to do this in another class. How can i make to access the textbox control from my class? the WPF window is named AddStudent and the class i want to make the check is named Consiste. I made Consiste static so i can use it on my AddStudent without creating an instance.
In you Util class, you must just have method with input parameter
public static bool Validate(string firstName, string lastName,string gPA)
{
if(firstName.Length < 1)
.....
return true;
}
And call this static class Util
Util.Validate(FirstName.Content, LastName.Content, GPA.Content);
In general it's not considered a good idea to be passing your UI elements into your backend code (even helpers within your UI project).
Presumably the AddStudent form is calling a method on the Consiste class. Rather than having the Consiste class reach back into the form to get at the textboxes, your method call should be passing the values to the Consiste class.
If you're following the Model-View-ViewModel design pattern, which is recommended since that's the one WPF was designed for, then the general approach is like this:
First, create a ViewModel class to be the actual store of data. (The ViewModel should probably implement INotifyPropertyChanged, but I'll skip it here for the sake of brevity.)
public class MyFormViewModel
{
public string FirstName {get; set;}
public string LastName {get; set;}
public float GPA {get; set}
}
This class's properties are public, so they're visible from everywhere.
Then, create a form and use bindings to connect its fields to your properties:
<Window x:Class="MyNamespace.MyForm">
<StackPanel>
<TextBox Text={Binding FirstName}/>
<TextBox Text={Binding LastName}/>
<TextBox Text={Binding Gpa}/>
</StackPanel>
</Window>
And finally, when you instantiate the form create a new ViewModel to use as the form's DataContext:
var myFormContext = new MyFormViewModel();
var dialog = new MyForm { DataContext = myFormContext };
The reason for going through this extra effort instead of just coding against the UI directly is that it helps keep your code more organized. On down the road it's easier to reuse the same ViewModel classes with multiple views, or to rearrange your user interface without creating such a cascade of changes going through all your code. So for the long run following the MVVM pattern is a very good habit to get into right away.
As a concrete example of something that's easier if you structure your code this way, there's already a data validation mechanism in WPF that's built to work with MVVM code: the IDataErrorInfo interface. You can implement it in your ViewModel without too much trouble, and then add some markup to your bindings that tell them to expect validation, and you can be done there - though if you want to customize how the user is warned about errors, controls have an ErrorTemplate that you can style to suit.

Why does an IEnumerable<T> require a call to ToList to update the listview?

I'm sure there is good explanation for this. I'm guessing it has something to do with me having a cold and missing something obvious...
I have a simple window:
<Window x:Class="WpfIdeas.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:w="clr-namespace:WpfIdeas"
Title="Window1" Height="300" Width="315">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="20"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<Button Grid.Row="0" x:Name="btnAddObject" Click="btnAddObject_Click">Add Object</Button>
<ListView Grid.Row="1" ItemsSource="{Binding Objects}">
</ListView>
</Grid>
</Window>
the code behind the window is:
using System.Windows;
namespace WpfIdeas
{
/// <summary>
/// Interaction logic for Window1.xaml
/// </summary>
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
DataContext = new ObjectVM();
}
private void btnAddObject_Click(object sender, RoutedEventArgs e)
{
(DataContext as ObjectVM).AddObject();
}
}
}
And its DataContext is set to be the following class:
class ObjectVM : INotifyPropertyChanged
{
private readonly List<ObjectModel> objects = new List<ObjectModel>();
//public IEnumerable<ObjectModel> Objects { get { return objects } } //doesn't work
public IEnumerable<ObjectModel> Objects { get { return objects.ToList() } } //works
private Random r = new Random();
public void AddObject()
{
ObjectModel o = new ObjectModel(r);
objects.Add(o);
if(PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs("Objects"));
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
The ObjectModel class is in fact a struct that generates a 14 character string when it is instantiated. It's ToString() method just outputs this string.
As the code is above, when I click the "Add Object" button then a new string appears in the ListView.
However if I remove the ToList() call in the Objects property, nothing is ever displayed in the ListView. It just remains blank.
Why is this?
Using Collection Objects as a Binding Source:
You can enumerate over any collection that implements the IEnumerable interface. However, to set up dynamic bindings so that insertions or deletions in the collection update the UI automatically, the collection must implement the INotifyCollectionChanged interface. This interface exposes an event that must be raised whenever the underlying collection changes.
objects.ToList() will create a new list on each Button-Click. This is probably the cue for the list to refresh itself?
I'm guessing here... But when you NotifyPropertyChanged, then the framework might check to see if the property really did change (it didn't in the return objects case - it is still the same list).
If you raise the PropertyChanged event on a property, the binding checks to see if the value of the property has changed, and refreshes the target if it has. Since Objects is a reference type, its value only changes if you assign it to a new instance - which is what using ToList() or ToArray() does.
In other words, when your code raises PropertyChanged, you're not asserting that the list's contents have changed, you're asserting that the property contains a new list. Binding checks the property on the source against the property on the target and disagrees.
This is why you should be using an ObservableCollection<T>, or some other collection that implements INotifyCollectionChanged. IF you bind to a property that implements INotifyCollectionChanged, binding will listen to both PropertyChanged events (raised if you create a new collection and change the value of the property) and CollectionChanged (raised when items are added to or removed from the collection).
Also, note that it's not enough to change your underlying collection to an ObservableCollection<T>. You have to change the type of the property you're exposing. Binding won't try to listen to events on an IEnumerable<T> property, because those events aren't exposed by that interface.
That's most commonly because the IEnumerable is the result of a Linq query and the actual type is something entirely different than a simple List<> or Collection<>. What happens is that it (Linq) builds a logical representation of the 'query' but does not run it right away, instead running it when values are requested and yielding each value. That's one of the basic concepts of Linq. Different flavors of Linq may choose to implement it differently under the covers, but the concept is the same.
Actually nevermind, I should read the code more carefully when I answer; I don't think there's any way that happens with your code because you're just instantiating the List. However, ListBox never exposes items directly, instead wrapping them in an ICollectionView. The ICollectionView may have something to do with this, opting to lazily load the items if the type is seen as IEnumerable. Not sure though. It may also depend on the internal structure of ObjectModel... although probably not, since that wouldn't be affected by the call to ToList().

What is the proper way to access a value internally?

In the following setter, I can access the property backing field directly or through the getter. Is there a scenario when one would be preferred over the other?
public string Name {
get { return this.name; }
set {
if (value == this.name) return;
// or
// if (value == this.Name) return;
// ?
this.name = value;
NameChanged.Raise(this, this.name);
// or
// NameChanged.Raise(this, this.Name);
// ?
}
}
There is a related question. How would you initialize properties in the c-tor?
public MyClass(string name) { this.name = name; }
// or
public MyClass(string name) { Name = name; }
I use this.name, for the reason that at construction time the instance might be in an invalid/unstable/undefined state, so Name-setter validation might falsely fail. Any other opinions?
I would say that "Name = name" is more correct, because if you were to declare the "name" property as virtual then someone could override your property behaviour, but your constructor would still bypass their logic.
Additionally properties can encapsulate behaviour such as raising change events, which you shouldn't bypass. No user can add a handler to your event until you have constructed the object. Therefore if you make a setting in a constructor where you have external events, it won't be raised.
EDIT
See the comments below for why virtual was a bad example.
My personal approach to this problem is
Only use a this qualifier when to do otherwise would result in incorrect behavior or a compilation error.
I prefer to make my code readable in the abscence of a this qualifier. If it's unreadable without a this qualifier I strive to change the code to be readable.
In this case, the difference between the syntax is that in one case the getter/setter get invoked, while in the other case they don't. Correct?
I think it would be best to use Name rather than this.name. This way, only the getter/setter have access to the "unprotected" variable, and you can confirm any invariants about this value looking only at the getter and setter rather than at the whole class.
My personal opinion is to preferably use the property unless that results in the incorrect behaviour. What it comes down to is that using the property indicates a commitment to the semantics of your class and the design of your API.
Obviously sometimes there are going to be exceptions to this rule... sometimes the 'property' means something distinct to the value of the backing field (in your example, the property raises an event). If the internal use explicitly needs to avoid the semantics of the property (you don't want the event to fire), then the backing field is the correct 'second choice'.
On an unrelated note, for better or for worse, the Microsoft StyleCop application specifically prefers the convention of accessing private fields with the 'this' prefix to differentiate access of local variables and class fields (rather than prefixing such as '_' or 'm_' or variants thereof... which ironically are the convention used in legacy .NET framework code).
I agree with the others; you generally want to use the property. The reason for this is that you will get the logic that comes with it. In WPF, for example, if you don't use the property and instead use the field PropertyChanged events won't be fired, which means that any controls bound to that property won't get updated. Of course, you can't call the property within the property or you'll end up with a stack overflow.
That said, there are times when you would want to avoid that logic entirely, and once in a while variable initialization falls under that. In that case, you want to use the field.
Accessing the field within the property could potentially lead to an overflow if you're not careful. I always access the property to avoid those potential situations.
In the following setter, I can access property backing field directly or through the getter? Is there a scenario when one would be preferred over the other?
only use it when there is a conflict with other variables in scope
There is a related question - how do you initialize properties in the c-tor?
If you have a property, use the property
I you don't want to raise the PropertyChanged event, access the field instead of the property. However, in the constructor, you don't really care about raising that event, since you know for sure that no one has subscribed to the event yet...
My recommendation is that if you have access to the field and the field does not require special logic. An example:
private int width;
public int Width
{
get
{
return width;
}
set
{
if (value < 0)
throw new InvalidArgumentException("Mass cannot be below 0");
width = value;
}
}
In this case you would NOT want to access the field, because you (probably) cannot guarantee that the value you are setting is above 0.
However, if you have a property like:
public int Height { get; set; }
then it would probably be a good idea to access the field when possible.

Categories