Silverlight templated Control databinding to custom properties - silverlight

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));
}
}

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));
}

Is DataBinding to a composite object's fields possible?

I have a WPF window with controls I wish to bind to my model. The model implements INotifyPropertyChanged to notify the view when the Properties change value. The Properties are primitives backed by fields, e.g:
private bool m_isRunning;
public bool IsRunning
{
get { return m_isRunning; }
private set
{
m_isRunning= value;
OnPropertyChanged("IsRunning");
}
}
protected virtual void OnPropertyChanged(string propertyName)
{
if (String.IsNullOrEmpty(propertyName))
{
return;
}
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
This works fine for primtiive values. I also have a composite object with various primitive properties and a hash table. Or, I'd like to bind to an ObservableCollection's Count property. I would like to bind my View controls to properties within the composite object, but I do not think this is possible. Something like:
<Run Text="{Binding Path=CompositeObject.SomeInnerProperty, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" />
This doesn't seem possible, but is there some other way? I feel like my only option is to expose properties that map in to the inner property of the composite object, but this seems like a lot of repetiion, e.g.:
public bool SomeInnerProperty
{
get { return m_myComposite.SomeInnerProperty; }
private set
{
m_myComposite.SomeInnerProperty= value;
OnPropertyChanged("SomeInnerProperty");
}
}
There's nothing wrong with binding to something like CompositeObject.SomeInnerProperty, however if CompositeObject does not implement INotifyPropertyChanged, then your UI won't get notified of the change and know that it needs to update when SomeInnerProperty changes.
Also, note that you can only bind to properties (with get and set methods), and not fields. So you can bind to public string SomeValue { get; set; } but you can't bind to public string SomeValue;
In regards dealing with repetitive code, I personally use some Visual Studio macros to write my public properties for me, so perhaps you could look into doing something like that if you don't want to implement INotifyPropertyChanged on your CompositeObject class. It should be noted that Macros were removed from Visual Studio 2012 though, so if you have a newer version you might need to use some other alternative like creating an add-in to run your macros
I had this same problem some time ago. Look at how I solved it:
MVVM INotifyPropertyChanged conflict with base class PropertyChange
Basically I created a Base class that implemented INotifyPropertyChanged and I made all my classes inherit from that base class and data binding worked fine.
You have two options:
If your model classes do not implement INPC, then create wrapper properties in your ViewModel like you suggested, or
Implement INPC in your model and just expose your main object in the ViewModel, you can bind as deep as you want as long as inner properties notify changes.

Binding to a field of a non-dependancy object

In my .NET 4.0 project I've got an object that has public fields and this object neither implements INotifyPropertyChanged nor inherits DependencyObject, and it will never do. However, I need a mechanism to "bind" to fields of this object in my WPF control. I know I can't do it directly as binding requires a dependency property (or at least, properties and notifying property changes), so what can I do to implement the binding functionality I need. I've tried something like this in my WPF control:
void FirePropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
public float Friction
{
get
{
if (CurrentObject != null)
{
return CurrentObject.Friction;
}
else
{
return 0.0f;
}
}
set
{
if (CurrentObject != null)
{
CurrentObject.Friction = value;
FirePropertyChanged("Friction");
}
}
}
public PlatformObjectTemplate CurrentObject
{
get
{
return GetValue(CurrentObjectProperty) as PlatformObjectTemplate;
}
set
{
SetValue(CurrentObjectProperty, value);
FirePropertyChanged("Friction");
FirePropertyChanged("CurrentObject");
BindShapes();
IntersectionComboBox.SelectedItem = CurrentObject.IntersectionStaticMethod;
}
}
public static readonly DependencyProperty CurrentObjectProperty = DependencyProperty.Register("CurrentObject", typeof(PlatformObjectTemplate), typeof(PlatformStaticObjectPropertyEditor), new PropertyMetadata(null));
My WPF control implements INotifyPropertyChanged, and my PlatformObjectTemplate does not have properties, just public fields like Friction. I need to bind to my object in XAML as such:
(in my control): //DoubleUpDown is from the WPF toolkit.
<tk:DoubleUpDown Margin="91,10,7,0" Name="doubleUpDown1" VerticalAlignment="Top" Value="{Binding Friction, ElementName=window, FallbackValue=0}" />
(in my main window):
<my:PlatformStaticObjectPropertyEditor x:Name="platformStaticObjectPropertyEditor1" CurrentObject="{Binding CurrentObject, ElementName=window}" />
I put a breakpoint in the getter of Friction property, and it tries to bind before the CurrentObject is bound, and because it is null, I can't read the correct friction value from the object. I've tried to fire Friction property changed in the setter of the CurrentObject, to populate the Friction when CurrentObject gets set, but that doesn't work either.
Ok, here are two requirements:
PlatformObjectTemplate will not use properties. It will have public fields.
I need a declarative way of binding as usual, just as I used in the XAML above.
I probably have got things over-complicated, and I must be missing some stuff. What is the most "correct" and "declarative" way of doing this right, within the constraints of my requirements just above?
Thanks,
Can.
object neither implements INotifyPropertyChanged nor inherits DependencyObject, and it will never. However, I need a mechanism to "bind" to fields of this object in my WPF control
poyra, I have this same situation. Because one cannot bind to instance fields, your best option is to create wrapper classes which implement INotifyPropertyChanged.

Silverlight updating my source objects, how to update my UI

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

What's the point in setting up dependency properties, when PropertyChangedEventHandler does the job?

Currently I have use the following approach to setup change notification on any of my properties that I bind to in xaml:
class MyClass : INotifyPropertyChanged
{
string name;
public string Name
{
get { return name; }
set
{
name = value;
NotifyPropertyChanged("Name");
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
However, I've seen that to implement a dependency property I need to do stuff like registering it and setting callbacks etc, which in turn will just end up calling the above code.
So what's the point of setting all the extra boiler plate stuff for dependency properties when I can just use the above approach?
Thanks.
Dependency properties can be the target of a binding, whereas regular CLR properties can't. That's why the properties of a control (binding target) are usually dependency properties, whereas the properties of a model or ViewModel class (binding source) are not.
What you are doing is correct (assuming I understand it correctly) dependency properties are not for the things you bind to in the model they are for the properties in controls that the model will be bound to - for example the Text property in a text box.
There are a number of reasons to use them in your custom controls, not least of which is the automatic plumbing that comes with them so that they will correctly bind to a property declared as in your example.

Resources