Look at this:
<ItemsControl ItemsSource="{x:Static local:Cache.Colors}" />
This binds the ItemsControl to a static property called List. In this case, the Colors property is part of a class called Cache.
But there is a problem. When you bind in this way, the Colors property is called during the Initialize method, prior to when Security is established in the application.
Because Security has not been established, then calling Colors results in an exception as Security is a requirement for successfully calling the data service.
The solution moves this from XAML to code behind and ensures it is executed in the Loaded event instead of in the constructor during Initialize.
The real problem here is, I would like to do this in XAML. Is it possible?
I have typically solved this by having the ItemsSource being bound to implement the INotifyCollectionChanged interface. At initialization the items source would be empty, and then at load time the items source is populated. The population of the items source raises the collection changed event, causing your items control to rebind/add the new items in the source.
My solution was to run it in the App.xaml.cs before anything else.
Related
I have this problem with my listview itemsource, you see I'm working in WPF, and the problem comes (I think) in VB, its like blocked, this new columns I added I cannot see in xaml, the columns are there but no info, and I can see the values if I put some breakpoints in the part I specify the itemsource list, and when I do this shows up:
That lock there most be the cause of my problem, but I do not know how to take it off my collection list. HELP PLEASE.
By the way I'm using properties to create a row and later bind that to xaml
You can't see that property in the list view because it is marked as Private. According to the documentation all binding source properties must be marked as Public.
Binding Sources Overview | Microsoft Docs:
Implementing a Class for the Binding Source
(...)
Other Characteristics
The properties you use as binding source properties for a binding must be public properties of your class. Explicitly defined interface properties cannot be accessed for binding purposes, nor can protected, private, internal, or virtual properties that have no base implementation.
The little padlock that you see on the icon doesn't mean that it's locked, it's just an indication that the property is marked as Private.
I've been binding a Collection to a ListView and now I'm curious about the way this happens for WPF.
The main question is How WPF accesses the items of the collection? GetEnumerator is never called when binding.
Thanks
In my WPF GetEnumerator is called. I do not know how you came to this conclusion but if you implement the interface and set breakpoints you can see as much. The binding system however also checks for IList and may access items via the Count & indexer, GetEnumerator seems to be called regardness though.
I have a Dictionary whose ValueCollection consists of classes, which is exposed as a property in my VM, and bound to a DataGrid on the UI. My problem is that the Dictionary is populated asynchronously (it's actually an ObservableDictionary, so I can monitor change events), and no results ever show up in the grid. I'm raising the PropertyChanged event in the VM for the property the DataGrid is bound to whenever an item is added to the Dictionary, but can't get any results. I have verified that the events do fire.
If I use a straight ObservableCollection instead of an ObservableDictionary, everything is fine, and I don't need to raise PropertyChanged even, but I really wanted to use Dictionary to hold my collection to keep a unique key on each entry.
Am I doing something wrong, or is there a workaround with a different collection that I could use? I've also tried calling .ToObservable() or .ToEnumerable() on the value collection for binding.
The problem is that your ObservableDictionary probably implements INotifyCOllectionChanged (good), but your ObservableDictionary.Values does not.
Override the non generic IEnumerable.GetEnumerator method on your dictionary to return just the values instead of KeyValuePairs and bind the dictionary to your grid.
The problem was solved by returning Dictionary.Values.ToList() in my VM instead of just .Values, .Values.GetEnumerator(), or .Values.ToObservable(). I did have to still raise PropertyChanged in my VM for the VM property returning the list.
I have a main view that binds to subviews like this (the backing property is of type object):
<ContentControl Content="{Binding WalletsView}"/>
Now, I've added another property to the corresponding viewmodel, namely
public SmartObservableCollection<Selectable<Type>> PriceGrabbers {get; private set;}
where SmartObservableCollection is derived from ObservableCollection to make multithreaded updates easier.
Now I get a lot of binding errors (in fact, all bindings in the sub viewmodels run through the debug window) like this (interestingly, if I remove the PriceGrabbers property again, all errors disappear):
System.Windows.Data Error: 40 : BindingExpression path error: 'OverviewHidden' property not found on 'object' ''MainWindowViewModel' (HashCode=30986197)'. BindingExpression:Path=OverviewHidden; DataItem='MainWindowViewModel' (HashCode=30986197); target element is 'ColumnDefinition' (HashCode=22768693); target property is 'NoTarget' (type 'Object')
So the binding engine apperently tries to find any and all bindings on the main viewmodel.
The bindings work perfectly fine. While this is okay, I'd rather have errors go away. Did anybody of you already encounter this problem, and if yes, how did you solve it?
The problem isn't with WPF but with my usage of MEF as composition container. The property modifies the import order of classes and the ViewModel coresponding to MainWIndow is assigned to all Views first, after which the correct one is assigned. When the data context is refreshed, all bindings are renewed, thus the application works.
edit and now I found the complete reason for it.
SmartObservableCollection takes an Action<Action>> parameter to execute on CollectionChanged events, this is needed due to most of my collections getting updated in a multithreaded manner, but the events have to be executed in the GUI thread, otherwise you will get an exception.
For this, my Views expose Dispatcher.Invoke() and Dispatcher.BeginInvoke() as methods, which I then supply to the collection.
At startup, the DataContexts are assigned in the base class ViewModel by the following lines:
Dispatcher.CurrentDispatcher.BeginInvoke((Action)delegate()
{
view.DataContext = this;
});
Who has an idea already?
The reason for this hickup was the simple fact I supplied the Dispatcher.Invoke() method instead of Dispatcher.BeginInvoke() to the collection. By doing this (and the fact it was used in the MainWindowViewModel), it got executed before any DataContexts got assigned to other ViewModels.
Now, the next step occurs - the WPF engine tries to bind to the data in the sub views. As DataContext is null, the binding engine walks up the visual tree until it finds a set DataContext, in this case the first set DataContext is in MainWindowView, and it is MainWindowViewModel. Now, after the collection finished, all other actions get called and the DataContexts are assigned appropiately, thus reexecuting the binding engine which finds a non-null DataContext on the sub views and binds correctly.
I have a an object which is set to the DataContext in a Window. I have textboxes in the window which are bound to the properties on the object. There seems to be a delay however before the properties on the object are updated.
<TextBox x:Name="txtPropertyOne" Text="{Binding Path=PropertyOne,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" />
If I change the values in a few textboxes then quickly try to access the properties to which they map, sometimes there are changes which aren't reflected in the properties of the object. I thought that was what the PropertyChanged UpdateSourceTrigger was supposed to take care of.
If I change the values in a few
textboxes then quickly try to access
the properties to which they map
I can interpret this statement in two ways:
You're trying to access the values on a background thread. In that case, you may be accessing the properties before the UI thread has had a chance to do its thing.
You're using a separate message on the UI thread to check the values. Bindings are updated at a priority lower than Send and Normal. So if your message is priority Send or Normal it will be processed before any pending binding updates.
If this doesn't answer your question, please clarify what you mean by "quickly trying to access the properties".
The basic rule of WPF Databinding is simple:
The target property must be a
dependency property, and you're
already correct, it's bound to Text
property of TextBox.
The source property can be a CLR
object (other than any derived WPF's
DependencyObject), but the object
must employ or implement its own
INotifyPropertyChanged.
Have you you already implemented INotifyPropertyChanged on your object?