Has anyone used this control? Is there something I am missing? I created a WPF interface to tune a PID controller (just a line follower built from NXT) and I am trying to adjust my constants using the DoubleUpDown control, I can bind to the properties in my service no problem and see them so the getter is getting called but when I change values I never see the setter fire off (i.e. breakpoint never gets hit).
Any advice would be great!
Thanks...
Here is some code to go with this, this is just a normal dependency property - in this case value is getting assigned to a double that is part of the service (my datacontext) but that isn't any different from when I use an adapter at work on some boring business form - Lego's are way cooler...
public double Kp
{
get { return service.kp; }
set
{
service.kp = value;
OnPropertyChanged("Kp");
}
}
Even if there was a problem there (setting the field in the service) I should at least be able to put a break point at service.kp = value and see it trying to set it, and yeah - I will post this over at the wpf extended toolkit forum as well.
Make sure your constants are actual public dependency properties, or public properties on a class that implements the INotifyPropertyChanged interface. You should post this in the Discussions on the Extended WPF Toolkit project site. Also check your output window for any binding errors. Can you provide some code?
http://wpftoolkit.codeplex.com/
UPDATED:
Based on the code you provided in the Discussions section of rthe project site; you should bind the property to the Value proeprty of the DoubleUpDown control and not the Text.
Related
I have a user control that programmatically sets up its command bindings and content.
I also serialise this control to XAML. I do not want the content or bindings to be serialised since I set these up. Content is taken care of by overriding:
public virtual bool ShouldSerializeContent()
And I was pleased to see an equivalent for command bindings:
public bool ShouldSerializeCommandBindings()
However, this function is not virtual, and hiding it by specifying new in my implementation appears to do nothing? This does appear to be the recommended way to use it according to this MS page:
http://msdn.microsoft.com/en-us/library/53b8022e(v=vs.85).aspx
I have also tried shadowing the CommandBindings property and using [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)], but this just breaks my bindings.
Can anyone show me the correct way? Is this a bug?
Aha, nevermind I've sorted it. The trick is indeed to shadow the property, but I wasn't providing any implementation. The following works to turn off serialization:
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public CommandBindingCollection CommandBindings
{
get
{
return base.CommandBindings;
}
}
I have extended my domain service using a "shared" code file to add an additional property to my "Booking" class that calculates mileage from StartMileage and FinishMileage as follows:
public int? JourneyMileage
{
get
{
if (StartMileage.HasValue && FinishMileage.HasValue)
{
return (FinishMileage - StartMileage);
}
else
{
return null;
}
}
}
StartMileage and FinishMileage are properties in my autogenerated domain service.
The property JourneyMileage is bound to the UI, as are StartMileage and FinishMileage.
How do I update the JourneyMileage property (and therefore the UI as well) when StartMileage or FinishMileage are changed? I have been looking for something like NotifyPropertyChanged but seem to have drawn a blank.
Add to your shared Booking class a conditional silverlight code block like this.
#if SILVERLIGHT
partial void OnStartMileageChanged(){
RaisePropertyChanged("JourneyMileage");
}
partial void OnFinishMileageChanged(){
RaisePropertyChanged("JourneyMileage");
}
#endif
This should work. Don´t tested it.
Another way is, if you don´t need the JourneyMileage property on the server side, to create a partial "Booking" class on the client side, define your property and put my code without the conditional statement in the partial class.
You do NOT update the JourneyMilage property. It changes when the other fields change.
If you want to notify others that its value has changed, implement INotifyPropertyChanged and raise the PropertyChanged event for JourneyMilage too when either StartMilage or FinishMilage change.
EDIT
See this post
This should work. Don´t tested it.
1) This won't be compiled with Silverlight, if you need property changed notification. The generated shared class on the client side is from another namespace (other .dll in SL) and has other method signatures for raising property changed :-(
Another way is, if you don´t need the JourneyMileage property on the
server side, to create a partial "Booking" class on the client side,
define your property and put my code without the conditional statement
in the partial class.
2) This will work and could be a reasonable solution, however you can't then share the business logic with the EDM :-(
3) One other solution could be to add the property to generated metadata class with [DataMember] attribute. The disadvantage (or in some use cases advantage) is that changing such property will set context as changed.
I can use data binding to set the initial Content of a WPF Frame, but subsequent changes to the the bound property (implemented using INotifyPropertyChange) do not seem to change the content.
Also, does anyone know if binding directly to the Content property in this way will cause the bound item to appear in the Frame or NavigationWindow's journal?
Some context: I realize that I should probably be using the NavigationService to interact with the Frame, but I'm attempting to follow the MVVM pattern. It seems like it would be much simpler to databind to the Content property...
You can use data binding against a Frame, but you need to make sure the Mode for your Binding is set to TwoWay.
XAML:
<Frame Content={Binding Path=MyProperty, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged} />
View Model:
public class MyViewModel : INotifyPropertyChanging, INotifyPropertyChanged
{
public Page MyProperty
{
get
{
return _viewModelPage;
}
set
{
this.OnPropertyChanging("MyProperty");
_viewModelPage = value;
this.OnPropertyChanged("MyProperty");
}
}
}
Many in the WPF community agree that the built-in navigation framework is broken. However, even if you were to use it, binding the Content property is not the correct approach. If you want to use MVVM with navigation you should combine it with the FrontController pattern where the ViewModel dispatches a navigation request to a Controller which then resolves that request for you. There aren't many examples of this concept available because (as I mentioned before) many developers pass on using WPF's built-in navigation.
If you want to look at a very robust navigation engine for WPF, look at nRoute It is a port of the MVC routing engine to WPF.
The Frame is a navigation host, so it is more correct to use the NavigationService to navigate to different content. If you use the INotifyPropertyChange, I suppose that you call the related event whenever the content is changed. Then, I also suppose that there is no difficult to use the NavigationService instead.
I ran into this issue a few days ago. I had a main window with a frame, and I loaded different pages into the frame (by using Navigate()). The pages' data bindings were broken, the data did not show up on the loaded page.
To repair the bindings, create or give your existing DataContext to the page inside the frame, and the bindings will work again.
Is there a way to know the first time a Dependency Property is accessed through XAML binding so I can actually "render" the value of the property when needed?
I have an object (class derived from Control) that has several PointCollection Dependency Properties that may contain 100's or 1000's of points. Each property may arrange the points differently for use in different types shapes (Polyline, Polygon, etc - its more complicated then this, but you get the idea). Via a Template different XAML objects use TemplateBinding to access these properties. Since my object uses a Template I never know what XAML shapes may be in use for my object - so I never know what Properties they may or may not bind to. I'd like to only fill-in these PointCollections when they are actually needed.
Normally in .NET I'd but some logic in the Property's getter, but these are bypassed by XAML data binding.
I need a WPF AND Silverlight compatible solution.
I'd love a solution that avoids any additional complexities for the users of my object.
Update
One way that I've found to do this is using Value Converters. In my situation I had multiple point collections. There was a main dep. property that contained the usual shape of the data. Two alternate shapes were needed for reuse in other areas/contexts.
At first I had 3 dep. props. But, I could have just had one property (the usual shape) and used a value converted to transform the points into my other 2 desired shapes. Doing this I only make the one set of points in the control. The expense of transforming points to the secondary shapes is only incurred when used. Now my main control doesn't need to anticipate how data needs to look for every possible template thrown at the control - now its the template designers problem.
Update 2
Certainly INotifyPropertyChanged and regular properties are the recommended way to handle this.
You don't necessarily have to use dependency properties to enable data-binding. However, you then have to implement INotifyPropertyChanged if changes at the source should be propagated to the target of the binding. A "normal" .NET property is easy to lazy load perhaps like this:
PointCollection points
public PointCollection Points {
get {
return this.points ?? (this.points = CreatePoints());
}
}
PointCollection CreatePoints() {
// ...
}
I'm not sure how you can fit INotifyPropertyChanged into your control, but it sounds a bit strange that your control supplies data to other parts of the system. Perhaps you need to create a view-model containing the data that you then can let your control data-bind to.
If I paraphrase your question to
How do I get notified when dependency property is changed?
will this be correct? I draw this from your phrase "Normally in .NET I'd but some logic in the Property's getter, but these are bypassed by XAML data binding".
If I'm correct, then you can register your own property changed callback. It's always called. Doesn't matter who caused the change binding, style or trigger. The following code snippet is taken from MSDN Article "Dependency Property Callbacks and Validation":
public static readonly DependencyProperty CurrentReadingProperty =
DependencyProperty.Register(
"CurrentReading",
typeof(double),
typeof(Gauge),
new FrameworkPropertyMetadata(
Double.NaN,
FrameworkPropertyMetadataOptions.AffectsMeasure,
new PropertyChangedCallback(OnCurrentReadingChanged),
new CoerceValueCallback(CoerceCurrentReading)
),
new ValidateValueCallback(IsValidReading)
);
public double CurrentReading
{
get { return (double)GetValue(CurrentReadingProperty); }
set { SetValue(CurrentReadingProperty, value); }
}
Your takeaway here is OnCurrentReadingChanged() method. Hope this helps :).
I am new to WPF and trying to wrap my head around WPF's framework, what it does and does not do for you.
To clarify this, I would like to know what is the difference between this:
public List<MyCustomObject> MyCustomObjects
{
get { return (List<MyCustomObject>)GetValue(MyCustomObjectsProperty); }
set { SetValue(MyCustomObjectsProperty, value); }
}
public static readonly DependencyProperty MyCustomObjectsProperty =
DependencyProperty.Register("MyCustomObjects", typeof(List<MyCustomObject>),
typeof(Main), new UIPropertyMetadata(new List<MyCustomObject>()));
and this:
public ObservableCollection<MyCustomObject> MyCustomObjects { get; set; }
public Main ()
{
MyCustomObjects = new ObservableCollection<<MyCustomObject>();
}
Ok, we must put some order into things, there's a few concepts mixed in together here.
First of all, you're asking what the difference is between a field-backed property and a dependency property. Google would be your best friend, however I recommend this blog post by WPF's vanguard Josh Smith: Overview of dependency properties in WPF
In short: dependency properties support the richness that is WPF: Styling, animation, binding, metadata, and more.
Secondly, you're asking what the difference is between a List and an ObservableCollection. Well the latter provides change notifications (in the forms of events) on any change to the collection (addition, removal, change of order, clearing, etc.), and the former does not. You can read more about that here: The ObservableCollection Class
In short: ObservableCollection provides change notifications which are required for the UI to automatically reflect changes in the view model.
In addition to Aviad and Reed's answers, I would like to point out a serious bug in your first code sample :
public static readonly DependencyProperty MyCustomObjectsProperty =
DependencyProperty.Register("MyCustomObjects", typeof(List<MyCustomObject>),
typeof(Main), new UIPropertyMetadata(new List<MyCustomObject>()));
The new List<MyCustomObject>() used as the default value will be created only once, so by default all instances of your type will share the same List<MyCustomObject> instance, which is probably not what you want... The only sensible default value here is null
In the first case, you're setting up a Dependency Property containing a List<T> instance.
In the second, you're making a normal CLR property, but having it setup as an ObservableCollection<T>.
For WPF Data Binding, there are some differences here.
Typically, you want all of your properties in the DataContext (which is the object that, by default, things "bind" to) to either implement INotifyPropertyChanged or to be a Dependency Property. This lets the binding framework know when changes are made to that object. Normally, though, you'd only use a Dependency Property if your working with a custom control - it's usually a better idea to have your object to which your data bound be a separate class, assigned to the DataContext. (For details here, see Josh Smith on MVVM or my recent detailed post on MVVM...)
However, with a collection, you typically also want the binding system to know when the items within the collection change (ie: an item is added). ObservableCollection<T> handles this by implementing INotifyCollectionChanged.
By using the second approach (using an ObservableCollection<T>), your UI can tell when items were added or removed from the collection - not just when a new collection is assigned. This lets things work automatically, like a ListBox adding elements when a new item is added to your collection.
1:
You're using a dependency property to "tell" the framework when that property is changed. This will have the following consequences for your binding:
MyCustomObjects.Add(new MyCustomObject()); //Wont update the view through databinding
MyCustomObjects = new List<MyCustomObject>(); //Will update the view through databinding
You could gain the same databinding functionality by implementing INotifyPropertyChanged on which ever class exposes the property, but dependency properties a capable of much more than just notifying about changes. These are rather advanced features though, which you aren't likely to come across in your average joe app :)
2:
You're using an observable collection, which implements INotifyCollectionChanged for you, to tell the databinding whenever the content of the collection has changed. This will have the opposite consequences than #1:
MyCustomObjects.Add(new MyCustomObject()); //Will update the view through databinding
MyCustomObjects = new ObservableCollection<MyCustomObject>(); //Won't update the view through databinding