Is there anyway to stop automatic DataContext inheritance in Silverlight? - silverlight

Is there anyway to stop automatic DataContext inheritance in Silverlight?
I Set my DataContext on my parent UserControl in code. As a result all the xaml bindings inside the UserControl try to bind to the new DataConext they get (through the automatic DataContext Inheritance).
The DataContext's for the children elements (actually they are children of children of children) of the UserControl is something I need to set in the UserControl's code... I don't want them being all smart because they end up binding to the wrong data object! :-)

Can you set the DataContext to {x:Null} in XAML, or null in code, for the items you don't want the inherited context for?

Related

WPF use one ViewModel for multiple UserControls

I've searched a lot for an answer for this question, but couldn't quite find an answer.
I have my main Window and 4 different UserControls. The Window is constructed from all 4 UserControls.
I have a class which is the Window's ViewModel.
I wish to set the DataContext of the Window and all 4 UserControls as the Window's ViewModel.
The problem is that writing the class as the control's DataContext creates a new instance of the class, hence, I can't use the containers I'm filling.
Any way of doing that?
DataContext gets inherited in WPF.
If you don't set a DataContext for the UserControl, they will automatically inherit their parent's DataContext (the Window), and should use your ViewModel directly.

Binding a viewmodel's property to another's

I have a main window coupled with a view model.This main window uses a usercontrol which also has its own viewmodel.
What I would like to achieve is setting a binding in the main window's xaml between one of its viewmodel's custom property and one of the usercontrol's viewmodel's custom property.
How would one go about doing that?
Could you instead use the ViewModels as projections of a Model?
That is, could you have a class that holds the state (or actions) that both the VMs need to expose and have both the VMs reference this class?
If for some reason you have to couple views to something outside their own DataContext I believe you can only go up the visual tree by using RelativeSource FindAncestor in the binding. I don't think you can traverse down (e.g. Window -> Control).
If you really want to Bind them together you could make your ViewModel's properties Dependency Properties and your ViewModel derive from DependencyObject - then you could do..
var binding = new Binding("Something");
binding.Source = myViewModel1;
binding.Mode = BindingMode.TwoWay;
BindingOperations.SetBinding(viewModel2,ViewModelType.SomethingProperty,binding);
If this is a good design having your viewmodels derive from DependencyObject is another question..
You could also try looking at this library that allows binding to and from POCOs.
I ended up not using a modelview for my usercontrol, not as neat but at least it works and is less complicated datacontext wise.
Thanks to all.

How to bind to a property of the parent of the item which is the DataContext?

I have a group of controls in a StackPanel container, in a user control, bound to different properties to an item which is the DataContext of the container, set as {Binding MyItem}
How would I bind one of those controls to the logical parent of this MyItem, if MyItem object has a property pointing to its parent?
If MyItem has a property pointing to its parent, then you can directly use that property to reference the Parent. Nothing special required for it, like:
{Binding Parent.PropertyName}
(unless I misunderstood the question)
It turns out that {Binding Path=Parent.IsEnabled} was enough, provided that the item which is the DataContext has a public property Parent. Probably earlier errors were due to other things.

WPF does not rebind if new datacontext Equals() previous datacontext

As explained on http://www.lhotka.net/weblog/DataRefreshInWPF.aspx
A WPF control sometimes does not rebind to the new datacontext. Specifically when using viewmodels that implement Object.Equals to see if viewmodels are logically equal. The problem here is that the control does not rebind to the new datacontext if it is logically equal to the previous. This causes the controls to become limp, they are not bound to the new viewmodel.
I circumvented this by first setting the DataContext to a new object(). This makes sure the control rebinds to the new datacontext. This does not work however when a viewmodel contains another viewmodel that implements Object.Equals. A view bound to that viewmodel using a DataTemplate will not rebind. How can I work around this?
Obviously WPF databinding should use ReferenceEquals instead of Equals..
UPDATE: I solved it for now by having the sub ViewModels implement IEquatable<T> instead of overriding Object.Equals.
I solved it for now by having the sub ViewModels implement IEquatable instead of overriding Object.Equals.

Update all bindings in UserControl at once

I need to update all the bindings on my UserControl when its visibility changes to Visible. Pretty much all my bindings are bound to the DataContext property of the user control so I'm trying to update the target of that binding:
BindingOperations.GetBindingExpressionBase(this, UserControl.DataContextProperty).UpdateTarget();
But I get null as the result of GetBindingExpression(..) method and I'm wondering if I'm using this wrong.
Also, is there any other good way to refresh all bindings on the control (which use DataContext as the source).
Well, you could just re-assign the DataContext:
var dataContext = DataContext;
DataContext = null;
DataContext = dataContext;
FYI, resetting the property to its value (i.e.DataContext = DataContext) won't work.
You're using the BindingOperations.GetBindingExpressionBase method on the wrong property. You have to use it on the properties which are binding to the DataContext property, not the DataContext property itself.

Resources