How does ResourceDictionary change result in DynamicResource reevaluation? - wpf

If Resources dictionary is not observable, how does DynamicResource reference work?
Do the Add / Remove methods of the resource dictionary have internal code that kind of "polls" all DynamicResource references and refreshes them when they are removed or added?

Each ResourceDictionary contains three list of owners. One for FrameworkElement, one for Application and another one for FrameworkContentElement. When you access the Resources property the owner is being set. Also each ResourceDictionary propagates its owner to merged dictionaries. When dictionary is changing, it notifies owners about it. This notification actually searches dependency properties with local values containing resource expression. Then each expression is forced to reevaluate.
All of this code is internal.

Related

What is the most minimal xaml element that can change a DataContext?

I'm wondering what element can be used, when the only thing you want to change is the DataContext.
I'm aware that I could wrap it in a grid or something, but all of those are rather heavy weight when I just need to change the data context for a single element, so that I can more easily bind to attributes without them getting too long.
The concept of the WPF class hierarchy is described at Microsoft: WPF Architecture. There you can find the System.Windows.FrameworkElement:
The two most critical things that FrameworkElement introduces are data binding and styles.
Checking the properties of FrameworkElement, there the DataContext property is defined. This means the following capability is available:
Support for data binding and dynamic resource references: The property-level support for data binding and resources is implemented by the DependencyProperty class and embodied in the property system, but the ability to resolve a member value that is stored as an Expression (the programming construct that underlies both data binding and dynamic resources) is implemented by FrameworkElement. For more information, see Data Binding Overview and XAML Resources.
The Data​Context property is now available and used at all inherited controls, which you can see at the following class hierarchy:

Listview itemsource cannot see values in xaml

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.

Why setting x:Name on Window.Resources items does not work

i just curious why when i access most controls via x:Name, for resources i do so using x:Key + i cannot access it from code (could using this.Resources["keyName"])
•x:Key: Sets a unique key for each resource in a ResourceDictionary (or similar dictionary concepts in other frameworks). x:Key will probably account for 90% of the x: usages you will see in a typical WPF application's markup.
•x:Name: Specifies a run-time object name for the instance that exists in run-time code after an object element is processed. In general, you will frequently use a WPF-defined equivalent property for x:Name. Such properties map specifically to a CLR backing property and are thus more convenient for application programming, where you frequently use run time code to find the named elements from initialized XAML. The most common such property is FrameworkElement.Name. You might still use x:Name when the equivalent WPF framework-level Name property is not supported in a particular type. This occurs in certain animation scenarios.
for that reason you have to use Key for the Resources
mor on http://msdn.microsoft.com/en-us/library/ms752059.aspx
You can access resources on any FrameworkElement as long as the element contains any resources. If defined in your markup, it must have a x:Key and cannot have a x:Name.
If a Button contains the resource for example, you must access it from its Resources collection.
var resource = button.Resources["myKey"];
If you want to find a resource from an object, its parents or the application, use FindResource() instead.
var resource = this.FindResource("myKey");
I don't understand your confusion.

How do I track all instances of a DataTemplate, or a control within a DataTemplate?

I'm using a DataTemplate to apply a View to a ViewModel. I have a case where when a certain thing happens in one instance of the View (DataTemplate), I need to take an action in all other instances.
I'm already accomplishing this by implementing the Initialized event on one of the controls in the DataTemplate, and using that event to add a reference to the control to a list in the codebehind. This is working, since there's only one codebehind for the DataTemplate (in a resource dictionary), they can all access the same list.
I'm a bit worried though, since instances of the DataTemplate get created and destroyed. Am I not keeping extra references around to old instances of the DataTemplate that are no longer necessary? Is there some way I can clean them up? Is there a corresponding event... the opposite of Initialized... when a control or DataTemplate is gone?
Would it be feasible for you to model this interaction directly in the ViewModel? Perhaps with a property or event on the item(s) being data-bound? That way your view only has to decide the behavior/presentation of the event.

DomainDataSource, binding and cursors

Databinding in WPF/Silverlight revolves around dependency properties, DataContext objects and DataSource objects. As far as I can tell, dependency properties are the same thing as ambient properties and their significance to binding is basically that if you put a bunch of widgets in a container then you only need to specify a DataContext for the container.
There are several parts to this question.
What is the difference between DataContext and DataSource, and how do they relate?
What manages cursors in WPF/Silverlight databinding? Is there a direct equivalence to the WinForms CurrencyManager and BindingContext?
How do I go about manipulating a Cursor in WPF/Silverlight databinding?
DataGrid seems to have a CurrentItem property. If you bind a bunch of widgets to the various columns of a datasource and they share the same datacontext as the datagrid then interactively moving the selected row in the datagrid changes the row whose values are expressed in the widgets. Could someone please explain to me how it all fits together? Preferably with reference to SL4.
When I do this:
private void buttonNew_Click(object sender, RoutedEventArgs e)
{
Guid newId = Guid.NewGuid();
Employee emp = new Employee() { Id = newId, FirstName = "NOT SET", LastName = "NOT SET" };
AtomDomainContext adc = employeeDomainDataSource.DomainContext as AtomDomainContext;
DomainDataSourceView ddsv = grid1.DataContext as DomainDataSourceView;
}
I get this compilation error:
The type 'System.ComponentModel.IPagedCollectionView' is defined in an assembly
that is not referenced. You must add a reference to assembly 'System.Windows.Data,
Version=2.0.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'.
D:\Argent\Views\ManageEmployees.xaml.cs, 57, 7, Argent
which sounds easy to fix but when I attempt to add a reference to the Argent project the list of references is empty; presumably one is confined to those assemblies that Silverlight deploys to the target computer. So now what do I do?
I found some answers so in the absence of a useful contribution from anyone else I'll answer my own question.
A DataContext is a kind of cursor object. You assign to the DataContext property any object or IEnumerable collection of objects to which you want to bind, and a wrapper is constructed around it. If you assign an IEnumerable, the DataContext surfaces a CurrentItem property that references one of the elements of the IEnumerable. If you assign something that isn't an IEnumerable, the DataContext wrapper behaves as though it contructs an IEnumerable and adds your object to the collection and then proceeeds as if that was what you passed in the first place, the object being set up as the CurrentItem.
One possible IEnumerable is the DomainDataSource, for which DataSource is a base clase.
Every widget in Silverlight has a DataContext property. Generally you don't set this directly, due to what Microsoft has taken to calling "dependency properties" which as far as I can tell are exactly the same as ambient properties, which is to say that unless you set them explicitly they "inherit" a value from the immediate container, which may in turn so inherit. So instead of setting the same IEnumerable as DataContext on a bunch of widgets, you make them all children of some container and set the DataContext for that, and they all miraculously get bound to the same cursor.
You can create a new DataContext object in XAML simply by explicitly specifying it; this creates a new instance and assigning it to the DataContext property of the widget on which you specify it; this is a new instance, a new cursor that is independent of any other DataContext.
In Silverlight4 you can reference the DataContext in use by another object; see element binding.
But a binding is only partly specified by a DataContext. Having specified a DataContext so that a widget has object foo contributing its context, specifying a binding path of A will look for a property named A on object foo and if this is found will mashall its value to and from your widget.
What's really confusing to the newbie is that while the whole binding can be specified in one spot, normally the context is specified miles away up a big complex container hierarchy, and just the path is specified on each widget, yet for (eg) binding the ItemsSource of a combobox to a lookup table you do specify the whole thing. I hope I've made it all a bit clearer for those following in my footsteps.
As for the location of the elusive 'System.Windows.Data', it's in %ProgramFiles%\Microsoft SDKs\Silverlight\v4.0\Libraries\Client\System.Windows.Data.dll

Resources