I have two User Controls in my window, both are bound to the same context.
One of them is getting updated and the other is not.
What could be the reason?
Sounds like you have an issue with the bindings. Make sure your dependency properties bound to each control are both getting notified via OnPropertyChanged. If both properties aren't getting notified this would be your issue regardless if they share the same datacontext (viewmodel).
Blessings,
Jeff
Beware of UserControls by default they bind one way you have to specify TwoWay:
<Binding Mode="TwoWay" ...>
...
</Binding>
Do you see any binding errors in the Output window? If so you can post that and maybe we can understand.
If not try to put a dummy converter in the binding and see if its methods are hit.
One from the multiple issues could be binding source address is changed.
Without seeing the code, we only guess:
Check that the property names in the bindings are an exact match (including case). It is quite common to have typing errors that cause bindings to fail (silently).
Related
I'm writing markup extension. I have XAML like this
<TextBlock Text="{ui:Test SomeInfo}" />
and TestExtension with constructor taking one string argument. I'm getting "SomeInfo" string so everything is find. Now I want to nest extensions and write something like
<TextBlock Text="{ui:Test {Binding PropName}}" />
and it does not work as is. I had to add constructor which takes one argument of System.Windows.Data.Binding type.
Now I need to know
How should I retrieve a current value from the Binding object?
When should I do this? Should I subscribe to changes some way or ask for that value every time in ProvideValue method?
Update1 PropName should be resolved against DataContext of TextBlock.
Update2 Just found related question: How do I resolve the value of a databinding?
Bindings like this will not work because your MarkupExtension has no DataContext and it does not appear in the visual tree and i do not think you are supposed to interact with binding objects directly. Do you really need this extension? Maybe you could make do with the binding alone and a converter?
If not you could create a dedicated class which has bindable properties (by inheriting from DependencyObject), this however would still not give you a DataContext or namescope needed for ElementName or a visual tree needed for RelativeSource, so the only way to make a binding work in that situation is by using a Source (e.g. set it to a StaticResource). This is hardly ideal.
Also note that if you do not directly set a binding the ProvideValue method will only be called once, this means that even if you have a binding in your extension it may not prove very useful (with some exceptions, e.g. when returning complex content, like e.g. an ItemsControl which uses the binding, but you set the extension on TextBlock.Text which is just a string), so i really doubt that you want to use a MarkupExtension like this if the value should change dynamically based on the binding. As noted earlier: Consider converters or MultiBindings for various values instead.
I try to use MappingConverter (existed in our appication and worked nice) in this way:
<converters:MappingConverter x:Key="RewardTypeToSymbolConverter"
ElseMappingValue="BlaBla">
<converters:MappingEntry FromValue="{x:Static loc:SomeEnum.Value}"
ToValue="{Binding SomeStringInViewModel}" />
</converters:MappingConverter>
I get no exceptions, but my TextBlock show nothing. Breakpoint within a converter shows that ToValue property is NULL (but SomeStringInViewModel isn't).
Do anybody have some idea how can I use binding like this within a converter? Or using binding in resource is impossible?
Because Converters aren't in any tree, the DataBinding of the ToValue will not work.
Have look at Josh Smiths DataContext-Bridge-Pattern.
Converters are not in any tree, be it logical or visual. There should be no DataContext at all, if you want to do any kind of binding there you should specify a source (RelativeSource will of course not work) in addition to the path.
In any case, have a look at the output window of Visual Studio, the binding errors displayed there often help find the problem. Also see this article on debugging bindings.
It sounds like your DataContext is incorrect
I would recommend using a tool like Snoop to figure out what your DataContext is
in my scenario I have a Linq2SQL Data backend.
my Dataobjects implement IDataErrorInfo to catch errors like Name==null (fast to execute Validationrules that only require the value, nothing special so far )
the Dataobjects are organized in a tree-structure, so each has a Parent and Children
How can I validate if a chosen Name is Unique under the Children of a Dataobjects' Parent?
The problem I'm facing is, that the unique Name validation requires a Database roundtrip which lags typing if UpdateSourceTrigger="PropertyChanged" on the TextBox binding to the Name.
On the other hand, I could set UpdateSourceTrigger="LostFocus", but the problem with that is, that I enable/disable a "Save" button on valid/invalid data. Now in the invalid state you can't click the Save button, so there's no way the Textbox could lose Focus to update (only tabbing away which is ugly, but there are more "unusabilities" with LostFocus (e.g. Error keeps displaying while typing and thus changing the name).
what would be ideal was a way to say for individual validationrules to apply on different events like so:
<TextBox Grid.Column="1">
<TextBox.Text>
<Binding Path="Foldername">
<Binding.ValidationRules>
<wpfresources:UniqueChildValidationRule ValidationStep="UpdatedValue" **UpdateSourceTrigger="LostFocus"**>
... stuff here ...
</wpfresources:UniqueChildValidationRule>
<DataErrorValidationRule **UpdateSourceTrigger="PropertyChanged"**/>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
What is the best way to solve this?
EDIT
This MSDN article seems to suggest, that a BindingGroup would be the way to go. I'll look into that...
I finally figured a way to accomplish what I wanted.
The use of BindingGroup worked, but I stripped my solution down because what I needed essentially was a way to show a Validationerror in the correct Textbox.
I did so now with an attached property that I read out on execution of the "save"-functionality. then I manually validate and set a ValidationError on the textbox. that way the textbox can keep its PropertyChanged UpdateSourceTrigger and the lengthy validation is done on submit.
For what it's worth, validation that requires potentially arbitrary time (talking to a database over a network, e.g.) is one form of validation that does not need to be reflected in the UI in realtime. If you can work it so that it is (pre-caching the values that will be checked by reading them from the DB before you need them, e.g.), so much the better, but this is the one scenario where reporting an error after the user has submitted the data is generally acceptable as long as you don't destroy the information that the user entered.
I am currently stuck at a dead end with the following situation:
I have a List<Category> collection with each Category containing an Id, Name and a List<string[]> property called Subcategory (where array contains the Name and Id of that subcagtegory - I didn't feel like creating another class).
I have a TreeView with HierarchicalDataTemplate bound properly to categories and subcategories. I also have check boxes next to the tree node and I bind IsChecked to a MultiBinding of the Id of the sub/category and the an overall list of sub/categories that should be checked-off.
<CheckBox.IsChecked>
<MultiBinding Converter="{StaticResource IsCategoryChecked}">
<Binding Path="Id"/>
<Binding Path="myDataSet.Tables[Categories]/cat_subcat"/>
</MultiBinding>
</CheckBox.IsChecked>
The converter I use simply checks if the name of the sub/category I provide is part of the list (both are values I'm binding to). This works fine and overall I am quite happy with the result.
The problem comes with converting the check/uncheck back. When user changes the IsChecked value I must either add the Id of the sub/category to the list of all checked-off categories or remove that Id from it. Unfortunately when I've attempted to implement the ConvertBack() method for IMultiValueConverter, I only have access to the ACTUAL value that changed (the true or false value of IsChecked) and have NO access to the Id of the sub/category that THAT SPECIFIC CHECKBOX is bound to.
SOLUTIONS I'VE TRIED but failed miserably:
Saving the sub/category name when I do the initial conversion is not an option since I'm using the same Converter for ALL the sub/categories and thus I'd only save the last sub/category I've tried to convert.
Using a MouseUp/KeyUp event is useless because (for whatever reason) they fail to be triggered (a bug?).
I am contemplating to ignore the ConvertBack() and use Checked/Unchecked events instead but feel like that is a rather "dirty" solution because I might just as well ignore the bindings altogether! Is this the only way to go? I've ran out of options but still hope for a "good" solution, if it's out there!
You have a couple of options, and I've used both in production:
Overload Checked/Unchecked, as you've said, which gives you the most control over the situation
Add an IsCategoryChecked property to your strongly typed table in the code behind which handles the changes required behind the scenes, and you bind to the IsCategoryChecked property rather than using the converter
The second one works fairly well thanks to the partial classing with strongly typed datasets. However, it still isn't "seamless".
Is there an easy way to tell a Two-way WPF data binding to wait a few milliseconds after the last change before updating the Source with the new property value?
I'm implementing a filter feature for a ListBox where I have a textbox, and I want to filter the content of the ListBox according to what I type. I'm using data binding to connect the pieces together. Filtering the list can be quite time consuming, so I don't want to do it after every character that is typed: hence my request.
I have been using Paul Stovell's DelayBinding Extension (his site's down at the moment, so I can't link to it). However, I suspect that it is the cause of a memory leak in my applicataion (caused by it not removing event handlers).
Does anybody else have any other ideas?
I'm also a few years late, but if you're using WPF 4.5+ there is now an property exactly for this purpose, it's called Delay.
Description
The amount of time, in milliseconds, to wait before updating the
binding source.
Example usage
<TextBlock Text="{Binding Name, Delay=500}"/>
A little late to the question here (just a few years :) but for anyone who's interested I had a similar requirement in a project so I created two markup extensions called DelayBindingExtension and DelayMultiBindingExtension.
They work like normal Bindings with the addition that you can specify UpdateSourceDelay and/or UpdateTargetDelay, both of which are TimeSpan properties. Also, I've verified that it's leak-free (it makes use of the propertychanged callback of a dependency property binding through inheritance context rather than the DependencyPropertyDescriptor).
Example usage for a DelayBinding
<TextBox Text="{db:DelayBinding Path=TextProperty,
UpdateSourceTrigger=PropertyChanged,
UpdateSourceDelay='00:00:01'}"/>
And for a DelayMultiBinding
<cs:ColorSelector.SelectedColor>
<db:DelayMultiBinding Mode="TwoWay"
Converter="{StaticResource ColorConverter}"
UpdateSourceDelay="00:00:02"
UpdateTargetDelay="00:00:01">
<Binding Path="Red" />
<Binding Path="Green" />
<Binding Path="Blue" />
</db:DelayMultiBinding>
</cs:ColorSelector.SelectedColor>
Source code and sample usage for DelayBinding and DelayMultiBinding can be downloaded here.
If you're interested in the implementation details, you can check out my blog post about it here: DelayBinding and DelayMultiBinding with Source and Target delay
First, to answer your question, I would add the UpdateSourceTrigger binding extension which will let you control when the binding updates. Try LostFocus first but it sounds like you might want to go for Explicit.
Second, if your filtering takes a long time I would look into using CollectionViewSource on your ListBox. Bea Stollnitz has a good primer on it here and I used this blog post to show me how to filter. When I changed over I noticed a huge speed difference over my other implementation even though they use the same filtering functions. Also CollectionViewSource will automatically handle updating filtered items if the list you're bound to changes, even on the item level if you're binding to an ObservableCollection (this is the original reason I changed to CollectionViewSource).
HTH