Silverlight updating my source objects, how to update my UI - silverlight

I have a small silverlight app, where i have a list of objects with a Name and a Description. I databind them to a listbox, and show them, no problems.
However i want to be able to change the name or the description from my codebehind (updated through a webservice) and make the UI update, how to make the ui reflect the change of e.g. my name?
EDIT:
Made the binding twoway, implemented the interface INotifyPropertyChanged interface, still not working. Debugging shows that the PropertyChanged event is not assigned
public string Name
{
get
{
return name;
}
set
{
OnPropertyChanged("Name");
}
}
and the OnPropertyChanged method
private void OnPropertyChanged(string property)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(property));
}
}
I never get into the 'if', the event is null i.e. not assigned by anyone ???
SOLUTION:
Updated the setter to use the instance variable of 'name', tried it first with the property 'Name' this gave a stackoverflow :-)

Make the binding mode to be TwoWay. See here: http://msdn.microsoft.com/en-us/library/cc278072%28VS.95%29.aspx#direction_of_the_data_flow

Related

Dependency Properties: 'Freezing' DataBinding until user commits

I am trying to implement a system that would enhance WPF's DataBinding engine.
My prime concern right now is the following:
I would like to be able to 'freeze' the DependencyProperty - stop it from updating from the Model - once the user has started to input something in the UI.
Consider the following example:
I am binding a TextBox.TextProperty to some property on my ViewModel.
The user started typing inside the textbox, and the moment he starts to type, I want to prevent the ViewModel from updating the View.
Only after commiting the change, the user will see the update in the model.
I am trying to create some kind of MultiBinding using a a bool-flag which will tell me whether we need to update the GUI or not, but other than that I don't know how to continue.
Any help would be appreciated!
You can do that by setting UpdateSourceTrigger to PropertyChanged in binding and then set the flag accordingly in the setter of bounded property. PropertyChanged value Updates the binding source immediately as user will input any character.
xaml
<TextBox Text="{Binding Name, UpdateSourceTrigger=PropertyChanged}"/>
ViewModel
public class ViewModel:INotifyPropertyChanged
{
bool stopUpdate;
string name;
public string Name
{
get
{ return name;}
set
{
name = value;
stopUpdate=true;
OnPropertyChanged("Name");
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propName));
}

How can I get bindings to update when the value is changed?

I'm trying to understand WPF binding. As simple as it gets:
I have a ClassWithProperty that has a public uint Prop1.
The main window has a public ClassWithProp object and uses it for data context. This is set in the main Windows's constructor:
this.ClassWithProp = new ClassWithProp();
this.DataContext = this.ClassWithProp;
ClassWithProp's default constructor sets Porp1 value to 1.
The main windows contains a label:
<Label Content="{Binding Prop1}" ... />
It also contains a button that, when click, sets the ClassWithProp.Prop1 to 2.
When the window first appears, the label correctly shows 1. When the button is clicked the property's value is changed to 2, but the lable does not refresh.
Sorry - probably obvious but I'm a novice in WPF:
Why doesn't the bound label update when the undelying property changes?
Your ClassWithProperty needs to implement the INotifyPropertyChanged interface (which has just the one event on it, PropertyChanged), this way the WPF binding subsystem can listen for property changes and update the value. When you have changed the value of a property, you raise the event.
Here is an example:
pulic class ClassWithProperty : INotifyPropertyChanged
{
public uint Prop1
{
get { return _prop1; }
set
{
_prop1 = value;
OnPropertyChanged("Prop1");
}
}
protected void OnPropertyChanged(string propertyName)
{
if (this.PropertyChanged != null)
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
public event PropertyChangedEventHandler PropertyChanged;
private uint _prop1;
}
Implement INPC.
Also read the overview, it probably answers more than 90% of questions people have about data binding.

Re-establishing WPF databinding after changing property value

I'm playing with ICollectionView right now, and am encountering a problem where I think I understand the "why", but not the "how do I fix it". :)
I have a ComboBox that's databound to an ICollectionView, and it is initially set with the following code:
NameView = CollectionViewSource.GetDefaultView( names); // names is an IEnumerable<string> that comes from a LINQ query
NameView.CurrentChanged += new EventHandler(NameView_CurrentChanged);
Everything works great until I execute a piece of code that generates a new IEnumerable<string> and sets NameView again with the same code as above. Once I do this, CurrentItem is no longer working properly.
I've run into this problem before with ObservableCollection<string> databound to ComboBoxes, and I get around the "unbinding" problem by using Clear() and Add() instead of setting the ObservableCollection<string> property to a new ObservableCollection<string>.
My questions include:
1. If I wanted to be able to just set the property to a new collection, can I re-establish databinding with the new collection somehow? If so, how? If not, can you explain the WPFisms behind why this is fundamentally not possible?
2. What's the best way to deal with changes in an ObservableCollection<string> or ICollectionView? Is my approach of just Clearing and Adding the only way to do it?
When you bind your WPF Controls to ICollectionViews (Happens when the XAML is parsed withing your InitializeComponent-call - You should really define the bindings in XAML!), the Controls subscribe to the required events published by your collection (e.g. CollectionChanged).
Your collection property is just a reference to a memory address. When you bend this to a new collection (i.e. a new address), the DataBinding won't notice. You can't expect the original Collection to publish something like "IAmOuttaHere", and clearly the controls wouldn't listen to a new collection saying "I'm the new guy". But if I see this correctly, your snippet does nothing but add an eventhandler to the CurrentChanged (meaning your observe when some other item in the Combobox is being selected)
Binding is all about notification, so - as long as you don't tell your controls that the collection has been exchanged, they will stick to the initial collection. Please try to implement INotifyPropertyChanged like so:
public class ViewModel : INotifyPropertyChanged
{
private ICollectionView myCollection;
public ICollectionView MyCollection
{
get
{
return this.myCollection;
}
set
{
this.myCollection = value;
this.OnPropertyChanged("MyCollection");
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
if (this.PropertyChanged != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
public void ExchangeCollection()
{
this.MyCollection = new CollectionView(....)
}
}
Any bindings should be made to MyCollection. Although, personally, I don't define ICollectionViews myself, since they are not really as nice to work with as for example a nifty IList and they are auto-wrapped around any collection anyway as soon as a binding is defined.
Hope this helps
Sebi

Silverlight templated Control databinding to custom properties

Is there some trick that I'm missing here?
I've created a templated control, very simple. One single property on it, and I'd like to databind from the (viewmodel/datacontext of the) page in which it's hosted to a custom property on the control. The property will eventually be a vector type object, defining the position of the control, however in an attempt to get this to work I've tried reducing it to a basic string property.
Each time I'm faced with "Set property 'SimpleGame.Classes.Sprite.Property' threw an exception.".
I can't even catch the exception in a debug session, the set property code is not being executed.
Do I need to use a dependency / attached property or something? I wouldn't have thought so...
Can you give us some code sample. Usualy when you try to bind a property it must be a dependency property or a property that use INotifyPropertyChanged Interface implements like ths
private string m_prop;
public string Prop
{
get { return m_prop; }
set {
m_prop = value;
NotifyPropertyChanged("Prop")
}
}
private void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}

how do i get a wpf window to refresh?

I am building a simple roulette app. The player(UI) puts together a list of bets and submits them to the table object to be evaluated and paid out. I've got the code to work and the game process goes smoothly. The problem is that after a turn I can't get the player balance(textblock) or the betlist(listview) to update. Is there some sort of global window refresh command I am missing, or do I have to manually set each of these to update somehow?
WPF can take care of updating these values for you automatically, but you have to let it know when things have changed. Typically, this is done by using DependencyProperties on your model objects, but it can also be done by implementing INotifyPropertyChanged. In either case, when you update a property's value, the PropertyChanged event gets called; WPF automatically subscribes to this event when it binds to a value, and will update the UI when a change occurs. Without this notification, WPF won't check to see if the values in your object have changed, and you won't see the change reflected on the screen.
What about implementing INotifyPropertyChanged, and bind the balance and the betlist to the controls you are using?
Something like:
public class Player : INotifyPropertyChanged
{
private int _balance;
#region Properties
public int Balance
{
get { return this._balance; }
set
{
if (this._balance != value)
{
this._balance = value;
NotifyPropertyChanged("Balance");
}
}
}
public BindingList<Bet> BetList { get; set; }
#endregion // Properties
private void NotifyPropertyChanged(string propertyName)
{
if (this.PropertyChanged != null)
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
#endregion
}
public class Bet
{
// some code
}
For the binding list you wouldn't need to implement anything since it implements an interface that notifies changes to whatever is bound to (IRaiseItemChangedEvents). But then again you could be using a different approach.

Resources