I'm loosing it, I thought I would 'quickly' do a UserControl, add a dependency property to it and tests something, but it turns out that 'quickly' is likely to cause me to jump out the window of my 3rd floor office. I have a break point on my binding (SL5) and the FinalSource attribute (from locals) is pointing to the destination property of my control(with TwoWay binding this can almost make sense but I'm not using TwoWay binding). To add insult to injury, if I bind my control's DataContext everything works fine, if I bind my Dependency Property it does not work... (Maybe this is happening because its my last day of work for the year...). I don't know if I want an answer, but probably should, can anyone please explain this FinalSource issue to me?
Ok, found a workaround, instead of setting the control's DataContext to an instance of my presenter class I set the control's LayoutRoot's DataContext to an instance of my presenter class then all works fine. Irritating and bizarre...
Related
I'm just curious. For example, if the width of a custom user control is bound to the actual width of some other usercontrol, but then the width in the usercontrol is manually changed during some event. Will the property just go out of sync? Will the binding not work correctly? or will the property just be out of sync until the next time the source property changes?
Some more differentiation required. First: What kind of binding is it? If you have a OneWay binding then you will get out of sync when the target gets modified.
TwoWay or OneWayToSource will cause an update of the source (feed back)
In the case of OneWay changing the value will not remote the binding, as #goose noted when the source will trigger a PropertyChanged event the target destination will be resynced again.
If you wish to remove the binding, call BindingExpression.ClearBinding with the DependencyProperty you want to clear or BindingExpression.ClearAllBindings.
When a one way bound property is modified the binding will no longer work correctly. Even when the property is altered afterwards using the set method and NotifyPropertyChanged properly the width will remain unchanged.
TestScenario:
I've got a Control with a DependencyProperty A.
I've got a ViewModel with a property A that I bind against the Control's A-Property using the OneWayToSource Binding. The Binding is updated explicitly by the Control.
I switch out the bound ViewModel instance at runtime, thereby changing the underlying Source of my Binding.
When this happens I would like an Event to fire that tells my control that I can now update the value of its DependencyProperty A. The reason is, that as soon as you change the bound ViewModel, the DependencyProperty A's DefaultValue is written to the Source.
Instead, I would like the control to come up with a proper value and update the source manually.
One might think that just listening to the DataContextChanged event solves the problem. However, when this Event gets fired, the Source of the BindingExpression still points to the old ViewModel.
The only hackaround I can come up with, is to use Dispatcher.BeginInvoke with the DispatcherPriority.DataBind priority in the EventHandler of DataContextChanged.
It works, but does not feel clean to me.
I am looking for an event in the Binding-class that notifies me about changes of the Source... however I cannot find one.
Thank you
Perhaps I'm not understanding the question completely, but can you just use the NotifyOnSourceUpdated or NotifyOnTargetUpdated properties (and the corresponding SourceUpdated or TargetUpdated events)?
I'm moving project from Silverlight to WPF and I've come across a problem.
I have a control with an INotifyPropertyChanged property GeoRect of type GeoRect. GeoRect has a variety of public properties that are set in its constructor each of type IGeoPosition.
I am setting a binding to one of these properties like so:
<TextBlock Text="{Binding GeoRect.TopRight, ElementName=x_SomeControl}"></TextBlock>
In Silverlight the default ToString method is called on IGeoPosition instance every time the GeoRect property changes. In Wpf I don't get any text at all.
I can correct this in Wpf by adding a ValueConverter to the TextBlock which simply calls the ToString method on the object, but this appears to be unnecessary fat. Can anyone help?
I suspect that there is another problem in your binding. Also in WPF, data binding calls the ToString() method to build the text of a Text-control.
Have you checked the output window of visual studio for a binding error? Or maybe the GeoRect-class does not support INotifyPropertyChanged for the TopRight property?
I guess that ElementName=x_SomeControl and GeoRect.TopRight are causing a probable "Source and Path" comination error. Are you sure your x_SomeControl has a property called 'GeoRect'? Also is x_SomeControl.GeoRect not null? And x_SomeControl.GeoRect.TopRight has a correct value?
As HCL pointed out, this will become apparent when you view your Output window where BindingExpression error must have appeared for this binding.
Please check.
I've run into an issue I was surprised I couldn't find any discussion about (except WPF MVVM ComboBox SelectedItem or SelectedValue not working maybe).
I have a MVVM form that has 2 ctors, one is for "new item creation", the other is for "item modification". I have a combobox that represents one of the item's properties.
In the modification ctor, the property bound to ItemsSource is initialized, and then the property bound to SelectedItem is set. But nothing is selected in the UI, unless I delay (even a tiny bit) the SelectedItem set.
How can I solve this ? I decently can't keep a timer with a totally random interval to fix the issue :D
Thank you for your help
It seems like the elegant way to ensure the ItemsSource is initialized before I set the SelectedItem from VM is to have the binding source of ItemsSource (whatever it is) declared in my view resources.
I'm sure someone can lead me to the light now that I've pointed that out.
I have tried with a CollectionViewSource but didn't find the way to use its Filter capability without breaking the MVVM pattern. Plus I don't know how to re-raise the Filter as I used to with ICollectionView.Filter (filtered-out items depend on another combobox selection, nothing really fanciful imo).
Perhaps the resource declared in the view and used as ItemsSource has not necessarily to be a CVS, I'm looking for suggestions here.
--Edit--
I found out that the IsSynchronizedWithCurrentItem="True" solution spread all over the web is actually working. I was mislead because it didn't fix my problem at first try due to a remaining SelectedValuePath that wasn't used anymore on my control.
public MyViewModel()
{
this.Items = ...;
//this.SelectedItem = ...;
// select in separate message so that the ItemsSource has definitely been set
this.Dispatcher.BeginInvoke(delegate
{
this.SelectedItem = ...;
});
}
I've been exploring WPF and XAML for a while now, but have hit a slight stumbling block revolving around binding to a method.
My situation is:
There is a ComboBox bound to a DataTable. There is a ListBox bound to the return value of a method (GetDates) via an ObjectDataProvider. One of the input parameters of the method GetDates is an Id stored in the ComboBox/DataTable.
How can I bind a MethodParameter in the ObjectDataProvider to a particular value of the SelectedItem of a ComboBox (in this case, the SelectedItem is of type DataRowView)? Alternatively, am I missing a better way of solving this problem?
I can see ways out of it by using the code-behind, but I'd like to know if there's a more XAML-y solution. It's always useful to pick up little tips and tricks, even if it turns out not to be the best fix to this problem.
http://msdn.microsoft.com/en-us/library/system.windows.data.objectdataprovider.methodparameters.aspx
This seems to describe what I need - although it's actually trying to answer a different problem.
(Aside: Is it just me or is that example on MSDN trying to do too much all at once?)
By binding the ItemsSource of the ComboBox to a DataTable, and the SelectedItem of the ComboBox to a MethodParameter (with a converter to extract the value I need from the DataRowView), the ObjectDataProvider will have the parameter it needs.
It would probably be easier to read/follow/maintain if I just hooked into the ComboBox.SelectionChanged event.