Changing exisiting standard property to DependencyProperty - wpf

Is that possible to change for example MediaElement.Position property to DependencyProperty by inheriting MediaElement class and then creating DependencyProperty in a new class from inherited class?
How to do it? AFAIK DependencyProperty stops normal behaviour of default accessor, how to reconnect things to not break up after change?
I want to update Slider.Value through Binding thus I need MediaElement.Position as DependencyProperty. I know I can do it with DispatcherTimer but I think it's not professional solution.

You can create either a custom control (a XAML-less control that inherits from MediaElement) or a UserControl with a MediaElement somewhere in its visual tree.
In either case, create your DependencyProperty, and use the PropertyChangedCallBack (in FrameworkPropertyMetadata) to respond to changes made, and use events to listen the other way.
In either case, you are creating a new control to use instead of the MediaElement. The advantage of a User Control is that you only expose the properties needed. The disadvantage being naturally that you have to expose them all. The custom control will also expose the Position property even though you don't want to use it.

Related

How to apply FrameworkPropertyMetadata.AffectsArrange to a DependencyProperty

In a custom control I have a class which derives from DependencyObject and has a dependency property called MaxIdealWidth. I have several custom controls which do some pretty weird measure/arrange, and they all use this property in some way, but not in a binding.
My problem is, when everything is drawn the first time, it works well. However when the MaxIdealWidth is changed by one custom control, none of the others will do measure/arrange. I can understand why this happens, but I need to force all custom controls to measure/arrange at the same time.
FrameworkPropertyMetadata.AffectsArrange
Looking at the documentation, this looks like a promising way forward, however I have absolutely no idea how to apply it in practice. It doesn't seem to be documented from a point of view of how to use it in my situation. Can someone tell me how to apply AffectsArrange from XAML or code-behind to indicate from a custom control that a dependency property on the DataContext should cause measure/arrange?
You do that by using the FrameworkPropertyMetadata class instead of the PropertyMetadata for the last Parameter of the dependency propery Registration. There you set all the bits you like:
public static readonly DependencyProperty ArrowEndsProperty =
DependencyProperty.Register("your name",
typeof(<class>), typeof(<owner class>),
new FrameworkPropertyMetadata(<initial value>,
FrameworkPropertyMetadataOptions.AffectsMeasure));

WPF+MVVM: How to use plain old ViewModelBase when DependencyProperty is needed

I am using a 3rd party WPF control whose MVVM support relies on dependency properties on the VM it is bound to. The sample that comes with the control uses a ViewModelBase class derived from DependencyObject so all is well.
My ViewModelBase implements INotifyPropertyChanged and for various reasons it is unrealistic to change it to DependencyObject.
My question is how do I use my ViewModels with this WPF control? I guess what I need is something like "embedding a dependencyobject" or "plugging dependency properties" in a plain old ViewModel.
By the way my MVVM application is interface based, i.e. everywhere SomeViewModel is ISomeViewModel.
In general, a properly designed control shouldn't require binding to a DependencyProperty, as a DP can bind to any property without issue. As such, I'd revisit whether this is truly a bug in the control implementation first, and correct that.
However, if you must do this, realize you're going to violate MVVM - using DependencyObject within a ViewModel is, by its very nature, injecting view specific framework elements into the VM. Once you decide you're okay with doing this, you can always have your ViewModel expose a DependencyObject as a property, and bind to a DependencyProperty defined on that DependencyObject instead of directly to your VM's property.

Updating source using DependencyProperty in custom usercontrol

I got a binding source not being updated when the targeted DependencyProperty of a custom UserControl changes.
The source is a ViewModel loaded with MEF into the DataContext of my custom UserControl.
My binding looks like this in the root XAML of MyUserControl
// MyUserControl.xaml
<MyUserControlBase x:Class="MyUserControl" MyDependencyProperty="{Binding ViewModelProperty}">
If i use the MyDependencyProperty with a FrameworkPropertyMetadata and use the callback function when the property changes i can do the following which works fine
// MyUserControlBase.cs
private static void MyDependencyProperty_Changed(DependencyObject depObj, DependencyPropertyChangedEventArgs args)
{
var filter = (UserControl )depObj;
var vm = (ViewModel)filter.DataContext;
vm.ViewModelProperty= (VMPropType)args.NewValue;
}
Registration of the DependencyProperty in MyUserControlBase which inherit UserControl.
// MyUserControlBase.cs
public static readonly DependencyProperty MyDependencyPropertyProperty = DependencyProperty.Register("MyDependencyProperty",
typeof(VMPropType),
typeof(MyUserControlBase),
new FrameworkPropertyMetadata(null, MyDependencyProperty_Changed));
But why can't i get the simple two way binding to work when done in the XAML?
Output window show no binding failurs. I can see the ViewModel.ViewModelProperty getter is being called. Just not the setter once MyDependencyProperty changes.
It don't appear to be a problem with the ordering of events. The ViewModel is created long before DependencyProperty is changed for the first time.
I've also looked at Setting up binding to a custom DependencyProperty inside a WPF user control
But his problem seems slightly different since i actualy inherit from my own Base class which holds the DependencyProperty.
Thank you for any help.
Edit: with link to example solution.
Solution zip here
Sorry for the scary looking link, I don't know alot of quick fileshareing sites. If its bad post comment and I will remove it asap, but it seems ok.
Answer updated / irrelevant info deleted
After looking at the code in your sample I saw what the problem is. You have this "selector" control. In the BindDependencies method you set a binding on the MyControlBase.MyDependencyProperty. But at the same time you also bind this property to your control's datacontext (in MyUserControl.xaml). Effectively this means that in the BindDependencies method you are overwriting the binding to your viewmodel thus it is not active after that method - you can see this yourself by breaking into before and after the SetBinding call and calling BindingOperations.GetBindingExpression(control, MyUserControlBase.MyPropertyDependencyProperty) - the bindings are different. This is why your code does not work. I guess you will have to find another way of transferring the value there :)
Some additional info
In WPF a property can be a target of only one binding. This is actually very logical - if a property is bound to two sources - which one should it use? The fact that the binding is marked as OneWayToSource does not really matter in this situation as it still counts as a binding that targets the control's property.
One way you can investigate and see if it works for you is the MultiBinding - it does allow to bind the control's property to several sources by implementing your own IMultiValueConverter. You can find more info on this on MSDN in the link provided.
Do you expose the ViewModelProperty as a regular property..
Usually you do the following....
public static readonly DependencyProperty ViewModelPropertyProperty = DependencyProperty.Register("ViewModelProperty",
typeof(VMPropType),
typeof(MyUserControlBase),
new FrameworkPropertyMetadata(null, ViewModelProperty_Changed));
public VMPropType ViewModelProperty {
get { return (VMPropType)GetValue(ViewModelPropertyProperty); }
set { SetValue(ViewModelPropertyProperty,value); }
}
EDIT -- After comment.
When are you checking that the property has changed? By default WPF bindings only update the values when they lose focus, you change change the UpdateSourceTrigger property of the binding to alter this behaviour.

Change/Add control's objects from a static member

I've created a control with DependencyProperty. I need to change control's appearance when this property changes (even in design time). So, if properties is easy enough I can make bindings to them in XAML.
But in my case I need to change and add another objects/controls to it. I know about PropertyChangedCallback method, but it's a static method so I can't access to control's layout.
Any ideas?
Actually you can get access to your control within PropertyChangedCallback. Just cast sender to your control an do whatever you want(adding/deleting and so on).

DependencyProperty and DataBinding?

In WPF:
Can someone please explain the relationship between DependencyProperty and Databinding?
I have a property in my code behind I want to be the source of my databinding.
When does a DependencyProperty (or does it) come into play if I want to bind this object to textboxes on the XAML.
The target in a binding must always be a DependencyProperty, but any property (even plain properties) can be the source.
The problem with plain properties is that the binding will only pick up the value once and it won't change after that because change notification is missing from the plain source property.
To provide that change notification without making it a DependencyProperty, one can:
Implement INotifyPropertyChanged on the class defining the property.
Create a PropertyNameChanged event. (Backward compatibility.)
WPF will work better with the first choice.
What is the DependencyProperty?
The DependencyProperty class is one of the most important design bases hidden deep in the .Net Framework WPF.
This class is protected by sealed from the .NET Framework.
This property differs from the one-dimensional general property in that it not only stores field values, but also takes advantage of the various functions provided within the class.
Most importantly, there is a full foundation for data binding. You can also send notifications whenever you bind something.
DependencyProperty
Wpf Xaml Binding
It's already a late answer, but I'll introduce the results of my research.

Resources