How to confirm what properties are being bound to in XAML? - silverlight

I've got a "MainModelView" which implements INotifyPropertyChanged and has a property that exposes an ObservableCollection<T> called ExposedCollection. In our MainPage.xaml, we have a ListBox whose ItemsSource is supposed to be bound to MainModelView.ExposedCollection.
The MainModelView makes a REST call to populate the ExposedCollection in the background. When WebClient is done doing its thing, the ASyncCallback calls NotifyPropertyCHanged which checks if the PropertyChanged event is null, and if not raises it. Pretty basic stuff
Problem is, ListBox never seems to bind to ExposedCollection. I set a breakpoint on our null check for NotifyPropertyChanged, and there are never any listeners on PropertyChanged.
I've tried instantiating MainViewModel in PhoneApplicationPage.Resources, in PhoneApplicationPage.DataContext and the PhoneApplicationFrame.DataContext in App.xaml. In all cases the PropertyChanged event is still null. What am I missing here?
<phone:PhoneApplicationPage.DataContext>
<gmvm:MainViewModel x:Name="MainViewModel" />
</phone:PhoneApplicationPage.DataContext>
...
<ListBox x:Name="MyListBox" ItemsSource="{Binding ExposedCollection}" Margin="0,20,-12,0">
.....
</Listbox>

You should check the Output window in Visual Studio to see if there are any binding errors when running your app.

I'm not sure if it makes a difference, but have you tried implementing ExposedCollection as a Dependency Property? If you do that, it might eliminate the need for implementing the INotifyPropertyChanged interface and help with the binding to the listbox?
Crazier things have worked for me...

Related

How can I bind Text property of TextBox (VIEW) to a vaiable (in VIEWMODEL)

I am a newbie in WPF. I was exploring MVVM Pattern for WPF applications. I am having trouble in binding Text property of a TextBox from VIEW to a variable in VIEWMODEL
Here is the TextBox from MainWindow.xaml
<TextBox x:Name="UsernameTxt" Grid.Row="4" materialDesign:HintAssist.Hint="Username"/>
I just need to know how to bind its Text Property to ViewModel Class in Class Library
Thanks
I think it's possible to give a very generic answer to this very generic question.
If the question changes context this answer is very likely to be deleted but here goes anyhow.
You want your viewmodel to be in the datacontext of the textbox. Because datacontext is inherited down the visual tree this usually means you want to set datacontext of your window to an instance of the viewmodel. Or maybe the usercontrol your textbox is in, but we know nothing about your app so let's just cover the simple scenario.
Your options are to instantiate a viewmodel using code or xaml.
If you look at this article:
https://social.technet.microsoft.com/wiki/contents/articles/31915.wpf-mvvm-step-by-step-1.aspx
That instantiates in xaml.
Note the xmlns is
xmlns:local="clr-namespace:wpf_MVVM_Step01"
That's saying where you see some bit of markup which is prefaced "local:" then go get the class out of this namespace.
To point to a different dll ( a class library ) you need to tell it which assembly. You do that by adding ;assembly=Whicheverdll to your equivalent of that xmlns. And of course that won't be local then so give it a different name. You also need a reference to that dll or project added to the entry point exe.
Once you've done all that and your viewmodel is instantiated into memory and in the datacontext of that textbox you need some sort of binding.
Which the article covers but that will be something like:
<TextBox Text="{Binding YourPublicStringProperty}"/>

Wpf usercontrol dependency Property Binding

In my mainwindow I have got an UserControl, which ViewModel has got the Dependency Property "Message", I'm trying to bind the Dependency Property to an Property of the ViewModel of the Main Window, but actually it isn't Working, is there any soulution or is it genarally impossible?
Content of the Main Window:
<local:MessageLayer>
<local:MessageLayer.DataContext>
<local:MessageBoxViewModel Message="{Binding RelativeSource={RelativeSource AncestorType=Window, Mode=FindAncestor}, Path=DataContext.Message}"/>
</local:MessageLayer.DataContext>
</local:MessageLayer>
View models should not have DependencyPropertys in them and should certainly not extend the DependencyObject class, because these are UI related classes. I'm sure that you, along with many others have been confused by Microsoft's terribly worded error below:
A 'Binding' can only be set on a DependencyProperty of a DependencyObject.
This is really only referring to the UI element side of Bindings and not the data element side. For data binding data objects, we implement the INotifyPropertyChanged interface instead, which provides similar property change notification functionality to DependencyPropertys.
So, had you set the Window.DataContext to an instance of a view model that implemented INotifyPropertyChanged, with a property declared in it named Message, then your code would have worked just fine:
<local:MessageLayer>
<local:MessageLayer.DataContext>
<local:MessageBoxViewModel Message="{Binding RelativeSource={RelativeSource
AncestorType=Window, Mode=FindAncestor}, Path=DataContext.Message}"/>
</local:MessageLayer.DataContext>
</local:MessageLayer>

Binding to a System.Windows.Controls.Frame.Source property

<Frame Source="{Binding Path=ViewModelPropertyUri}" />
Is it possible to databind the Source of a System.Windows.Controls.Frame to a property on my ViewModel? From what I have tried so far I cannot make it work. It doesn't seem as if the Source property is being updated whenever the ViewModelPropertyUri value changes.
I'm fairly new to WPF and MVVM in general, but I get the overall idea and have the bindings working in various other scenarios.
Thanks!
I see nothing in the documentation on that property to make me think that you wouldn't be able to bind to that property.
Are you sure the PropertyChanged event is being raised when ViewModelPropertyUri value changes?

Silverlight: ViewModel trigger function in code behind

I have a bit of a problem with my Silverlight application, and my usage of the MVVM pattern.
In my View I have a DataGrid. The ItemsSource would normaly be bound to the ViewModel, but in my specific case I need the columns to be dynamic and my items collection consists of a Dictionary for each item, so I have no class properties to show. My solution was to generate all this in codebehind, since the actual design of the DataGrid has nothing to do with my ViewModel. This was the only solution I could think of since the columns can't be databound.
I have got all of this to work. My problem is that I'm using RIA and the view has no idea when the items collection has finished loading. I tried my design out by putting an ordinary button on the view to trigger the codebehind function, but obviously this solution is no good. I need my codebehind function to run as soon as my item collection has finished loading.
Can I make my codebehind listen to the ViewModel?
I have a feeling that you are messing up things somewhere.
For your question I think you can solve it by having an event in the ViewModel.
Subscribe to that event in your view's view_Loaded event and call the codebehind function in the handler.
I would recommend you to recheck your design and to see if this is really necessary.
I understand what you mean, we once had to do the same thing generating random columns which is a PIA in silverlight because you would need some kind of object that has a dynamic set of properties.
I see you've found the Dictionary solution. What I would suggest, which isn't per sé the cleanest solution but it is cleaner then putting the stuff in the code behind, is to add this in a converter. Then bind the collection to the itemssource of an itemscontrol and then when the list propertychanged is raised you assemble the datagrid in the converter.
small example:
<ItemsControl Grid.Row="1" ItemsSource="{Binding theListOfEntities, Converter={StaticResource theconverter}}"/>

WPF Update Binding when Bound directly to DataContext w/ Converter

Normally when you want a databound control to 'update,' you use the "PropertyChanged" event to signal to the interface that the data has changed behind the scenes.
For instance, you could have a textblock that is bound to the datacontext with a property "DisplayText"
<TextBlock Text="{Binding Path=DisplayText}"/>
From here, if the DataContext raises the PropertyChanged event with PropertyName "DisplayText," then this textblock's text should update (assuming you didn't change the Mode of the binding).
However, I have a more complicated binding that uses many properties off of the datacontext to determine the final look and feel of the control. To accomplish this, I bind directly to the datacontext and use a converter. In this case I am working with an image source.
<Image Source="{Binding Converter={StaticResource ImageConverter}}"/>
As you can see, I use a {Binding} with no path to bind directly to the datacontext, and I use an ImageConverter to select the image I'm looking for. But now I have no way (that I know of) to tell that binding to update. I tried raising the propertychanged event with "." as the propertyname, which did not work.
Is this possible? Do I have to wrap up the converting logic into a property that the binding can attach to, or is there a way to tell the binding to refresh (without explicitly refreshing the binding)?
Any help would be greatly appreciated.
Thanks!
-Adam
The workaround here was to add a property to my object (to be used as the datacontext) called "Self" , which simply returned
public Object Self { get { return this; }}
Then in the binding I used this property:
<Image Source="{Binding Path=Self, Converter={StaticResource ImageConverter}}"/>
Then when I call
PropertyChanged(this, new PropertyChangedEventArgs("Self"))
it works like a charm.
Thanks all.
I don't believe there is a way of accomplishing exactly what you need with your current converter. As you mentioned, you could do the calculation in your ViewModel, or you could change your converter into an IMulitValueConverter.
From your specific scenario (the converter tied to a ViewModel class, and a few of its properties), I would lean towards implementing the logic in the ViewModel.
Hmm, you don't show the full implementation. But I think it should update, if the value bound to the GUI provides the PropertyChanged-Event.
Regards

Resources