How can I overrule/change and then reset a Binding? - wpf

I have a Canvas whose Width & Height are databound, e.g. Width:
Width="{Binding DrawingSize.Width, NotifyOnTargetUpdated=True}".
When I set the Canvas's Width somewhere in code behind to another value, the Binding is lost.
Can somebody explain why that is or where MSDN explains it?

MSDN explains this in the Dependency Property Value Precedence:
Dynamic resources and bindings have the precedence of where they were
set, but the value is deferred. One consequence of this is that if you
set a dynamic resource or binding to a local value, any change to the
local value replaces the dynamic resource or binding entirely.
You can use SetCurrentValue to change the current value without overriding anything. However, even if there are valid usages for this method, I personally wouldn't recommend it. You're likely to run into other problems such as "who set this value, that's not the one I expected", or "the binding has changed too early, I lost my current value". Consider using the coercion mechanism, described in the same MSDN page, instead.

Related

Is there a XAML equivalent to AddHandler where you want to catch already-handled events?

According to UIElement.AddHandler on MSDN, you can pass in a boolean for the handledEventsToo argument so you can still be notified of handled events. Is there a XAML equivalent to this?
Another way to do this is through the EventSetter class which also specifies that property, but it specifically says it shouldn't be used in XAML although they don't specify why, and I can't think of a good reason why not.
Only thing I can think of is it causing havoc when initializing the XAML which (most likely) wouldn't be the case if you did it in code as you'd most likely do so after InitializeComponent. However, that's a complete guess.
I'm actually thinking of subclassing my own version of the EventSetter class that will add that property, although I haven't given it much thought yet, or even know if that's possible, although I don't see why it wouldn't be.
I was looking for the same thing but unfortunately, as per the latest MSDN documentation:
Setting the InvokeHandledEventsToo characteristics of how an event's
handlers will be invoked must always be performed in code, in keeping
with the general principle that there is no way to specify
InvokeHandledEventsToo when assigning defined event handlers for
instances directly to named events in XAML attribute syntax. Although
setting this value in XAML does not generate any compile-time errors,
the resulting XAML will produce a run-time exception when the style is
used.
I think the purpose of handledEventsToo is to give more flexibility to custom controls where code-behind isn't a problem, as opposed to when you are coding with the "normal" MVVM pattern.

WPF is it possible to temporarily change the Visibility Dependency Property of a DataGridColumn without destroying the original binding?

I have a WPFToolkit DataGrid with at least one column bound (via a proxy object as columns are not part of the visual tree) to a property. I wish to toggle all columns to Visible so that I can perform a calculation based on the DataGridColumnHeader (which is only created when its column is visible for the first time). Having done the calculation I want to reset the column to use the binding that was previously set.
I've attempted to get and store the Binding Expression etc, but with no joy. I have also attempted to use the DependencyObject.SetValue() method to change the property value non-destructively, but this doesn't event correctly change the value, let alone retain the original binding.
Any ideas?
You need to call SetCurrentValue() so that it won't clear the binding. SetValue destroys the old binding.
From MSDN:
This method is used by a component that programmatically sets the value of one of its own properties without disabling an application's declared use of the property. The SetCurrentValue method changes the effective value of the property, but existing triggers, data bindings, and styles will continue to work.
Given you have this
<TextBox Text="{Binding TestProperty}"/>
The SetValue you will overwrite the binding with whatever you provide. If you call SetCurrentValue, however, will ensure that the property takes on the given value, but won't destroy any bindings.
Be aware that you should not use SetCurrentValue in your dependency properties' setter/getter.
SetCurrentValue is more useful in scenarios where you need a property to take on a given value but don't want to overwrite any bindings, triggers, or styles that have been configured against your property.

Invoke WPF Setter manually

I would like to call a Setter (WPF specific) passed in a code behind.
void Invoke(Setter setter)
{
//I am interested what to do here, ?
}
the setter will be something like
<Setter TargetName="SomeUiElement" Property="SomeProperty" Value="{Binding SomeValue}" />
//resolution similar to
void Call(Setter setter)
{
setter.Property.SetValue(setter.TargetObject, setter.Value.GetValue())
}
Thanks in advance. Please be specific.
Setters are not quite what they seem. When WPF activates them, they don't strictly set a property's value (despite the name). Instead, they contribute a possible value, which may or may not have an effect on the property's effective value. (It depends on whether a higher priority property value source is currently active. http://msdn.microsoft.com/en-us/library/ms743230.aspx documents 11 different places property values can come from.) And when setters deactivate, they no longer offer that value.
The reason I mention this is to explain why a setter is never really "invoked". Invocation is instantaneous - it's a thing that happens at a particular moment. Setters, on the other hand, are active for some duration. (So there are two interesting instants: the point at which they become active, and the point at which they cease to be active.)
So if you're asking how to invoke a setter, you may not have the right tool for whatever job you're trying to do. The closest that can happen is that the setter becomes active, and remains active for however long you want it to.
Moreover, activation of a setter doesn't guarantee that its target property will actually change, because there may be other, higher priority value sources. Moreover, for it to be clear even what activation should mean, you need to know the way in which the setter is being used - the setters in the default style have a lower predence than those in a style defined by the application, which in turn have a lower priority than setters activated by a trigger in a template...
So a setter in isolation is meaningless, because its behaviour (i.e., what it does when it becomes active) is defined by the context in which the setter appears.
Now from your code, it looks like what you really want to do is arrange for the Local Value of the setter's target to be set to whatever value the property would acquire if a) the setter became active and b) that setter was the highest priority value available for that property. But that's not something a setter actually knows how to do.
Yes, it's ironic, but setters don't actually know how to set properties.
The code that causes the setter's value to become the target property value is actually distributed across various parts of WPF (including the Trigger and Style classes, amongst others). There isn't a straightforward way of getting WPF to do what you want, because it doesn't have a way of doing it in isolation - WPF's own processing of setters is mixed in with many other aspects of the property system. I'd strongly recommend trying to find some other way to solve whatever problem you were hoping to solve this way.

Why does BooleanToVisibilityConverter seem to return "Hidden" (not "Collapsed") when passed DependencyProperty.UnsetValue?

I've made a simple viewer of XAML documents that use a number of our own value converters, as well as built in ones, of course. It is expected behavior that there are DependencyProperty.UnsetValue bindings present.
I'm encountering a problem where the resulting view of my document acts like the built-in BooleanToVisibilityConverter is returning "Hidden" in that situation. I had expected it to act as if false was the value passed in. I was not even aware that "Hidden" was a possible result, and no such thing is mentioned in the MS docs.
Since I don't want to be changing the documents themselves to suit, I'm not planning to make a converter of my own that behaves as I expect. Any ideas out there to get what I want here, or even confirmation that what I'm seeing makes sense?
The BooleanToVisibilityConverter returns a Visibility. If you consult the documentation, you will find that Hidden is a valid value. A binding that results in DependencyProperty.UnsetValue will not attempt to convert this value via its associated converter. It effectively turns off the binding, i.e. it should have the same result as if the binding was not present at all.
In this case, your Hidden value will be coming from elsewhere. To understand the mechanism for determining a dependency property value, look at the documentation regarding dependency property precedence. In your case, it is most likely an inherited, or default value (but that is just a guess!)

Silverlight DependencyProperty.SetCurrentValue Equivalent

I'm looking for a SL4 equivalent to .NET 4's SetCurrentValue API, which would appear to be exactly what I need for my scenario.
In short, I'm writing an attached behavior that updates the value of a given property at appropriate times. However, I don't want it to overwrite any bindings that are set on that dependency property. I merely want to push that value to the property (and therefore have any bindings refresh based on that value).
From what I can tell, there's no easy way to do this yet in SL4.
Thanks
Silverlight does not provide direct access to this level of dependency value. However its this level of value that Animations in storyboards set when they manipulate a property.
Hence a Storyboard with a 0 length duration containing a single DiscreteObjectKeyFrame might achieve your desired result.
I've managed to simulate what I'm after by detecting bindings and injecting a surrogate object between the source and target. I can then manipulate the surrogate and have both sides of the original binding refresh.
It's ugly and more work than I'd like, but it seems to work.
Kent

Resources