Silverlight: How to start with element being invisible before biding? - silverlight

So, my stack panel should be hidden or shown depending on the binding to one of the properties on DTO. Problem is that there is a slight delay, so it flashes before it disappears when the property is set to false.

Use the FallbackValue of the binding... It will use the FallbackValue if it can't bind, then when the property gets set, the visibility will change.
<StackPanel Visibility="{Binding ShowImageVisibility, FallbackValue=Collapsed}">
</StackPanel>

Related

MVVM not binding after initial value has been entered

I'm facing an odd issue with my WPF (MVVM) project.
I have a few controls which bind to the properties in the ViewModel. INotifyPropertyChanged is configured, everything (initially works). I type in some values into my controls and I click a button. I can see, by stepping through the code, all the property values are what they should be. So far, it is text book.
Now I notice the issue. After I click the button, some logic is performed, such as saving these values to a database. I can then edit the control values and then save to the database again. The properties at this point to do not update.
Binding clearly works, because the output shows no binding errors and when I click the Save button, the properties are correct. However, after I click the save button, and then change the property values, the properties are not updatdd. I cannot fathom why this is the case.
As a trial, I added the PropertyChanged to the update source trigger and this seems to fix the issue, however, I've never had to do this before. Any ideas what could be wrong?
I don't believe the answer is 2 way binding (I am happy to be wrong) because it binds!
<TextBox Text="{Binding DataSource, UpdateSourceTrigger=PropertyChanged}" Grid.Row ="1" Grid.Column="2" />
Where as normally I would use
<TextBox Text="{Binding DataSource}" Grid.Row ="1" Grid.Column="2" />
UpdateSourceTrigger property determines the time, when the binding has to be updated. The default value for this property is LostFocus. So by default, after you type something and move the focus out, the binding will update. If you set the property value to PropertyChanged, binding will update immediately once you entered the value in text box.
http://msdn.microsoft.com/en-us/library/system.windows.data.binding.updatesourcetrigger(v=vs.110).aspx
In your case, the binding is updated on button click, since focus transferred to Button from textbox. Once the UpdateSourceTrigger set to PropertyChanged, the binding will update on every text change.

WPF OneWayToSource binding initial value

I have a RadioButton element whose IsChecked property is bound to MyProperty in ViewModel. The Binding has mode OneWayToSource for some reasons, it pushes the value from RadioButton.IsChecked to ViewModel.MyProperty.
RadioButton.IsChecked is initially false, now. I want to set an initial value from ViewModel, which might be even true. I cannot do that because the property is occupied by the binding.
Is there any way to use Binding with that mode and set default value to the bound property in UI? Something like that:
<RadioButton IsChecked="{Binding MyProperty, Mode=OneWayToSource, DefaultVaule=???}">
</RadioButton>
If I understood you correct, I think this might help:
You can define the default value through the TargetNullValue property. You can define a FallbackValue value in case of error either, for example:
<TextBox Text="{Binding MyProperty, TargetNullValue=0, FallbackValue=10}" />
see here:
enter link description here

Control in an ItemTemplate of a ComboBox loses its binding

I have a ComboBox that uses an ItemTemplate as shown below. Somehow the Text property of the text box defined in the item template gets disconnected from the binding and stops being updated when the selected item changes.
The ComboBox.ItemsSource is bound to a DependencyProperty that is list of CatheterDefinition objects. The ComboBox.SelectedItem is bound to a DependencyProperty that is a single CatheterDefinition object.
<ComboBox
AutomationProperties.AutomationId="CatheterInfoModelFieldID"
VerticalAlignment="Center" HorizontalAlignment="Stretch"
ItemsSource="{x:Static PumpAndCatheter:CatheterInfoViewModel.CatheterModelDefinitions}"
SelectedItem="{Binding ElementName=UserControl, Path=ViewModel.SelectedCatheterModel, Mode=TwoWay, NotifyOnSourceUpdated=True}"
SourceUpdated="HandleModelSourceUpdated">
<ComboBox.ItemContainerStyle>
<!-- A style used to set the AutomationID based on the item goes here -->
</ComboBox.ItemContainerStyle>
<ComboBox.ItemTemplate>
<DataTemplate>
<!-- This line below is the location of the problem -->
<TextBlock Text="{Binding Converter={StaticResource CatheterModelDefinitionToStringConverter}}">
<!-- A style used to set the AutomationID based on the item goes here -->
</TextBlock>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
I have an automated test that produces a very strange behavior (I saw the same behavior a few time during the initial development of the code, but was unable to reproduce it manually) - The test that reproduces this selects an item form the ComboBox, then goes to another part of the application and takes some actions that end up saving this change in a data model. When the test returns to the screen with this ComboBox, it tries to select another item from the ComboBox. The SelectedItem changes, and the values that it is bound to change, BUT the text in the ComboBox does not change - somehow the binding to the Text property of the text box gets broken (or something)... The binding still executes (the converter still runs when the selection changes and it converts to the correct value), but the text property is never updated.
Thoughts? (I can't provide an example of this because it is a huge application and it is only reproducible under one test that I know of)
Broken bindings are most of the time caused by not calling (or not correctly calling) the OnPropertyChanged("PropName") method.
Without seeing your underlying implementation, I would say that this is most likely the source of the problem.

How to set ItemsSource?

This dialog makes no sense to me
http://img576.imageshack.us/img576/4223/50709706.gif
And I'm having trouble finding good tutorials on it. Most of the examples aren't detailed enough, or do stuff via code, but I'd like to take advantage of the IDE as much as possible.
Whats the difference between ItemsSource and DataContext?
I'd like to bind it to just a List for starters. I don't need SQL or databases or anything fancy. Where would I declare my list? In MainWindow.xaml.cs? How do I get it to appear in that dialog?
Think of "DataContext" as the default value for "Source" in a binding.
When you create a binding, you can specify the path and source, like this (I'll use TextBox as an example):
<TextBox Text="{Binding Path=Foo,Source={StaticResource Bar}}" />
So my TextBox.Text property is bound to a Foo property on an object called Bar (a resource somewhere in the application).
However, if you have a whole bunch of things that you want to bind to properties on Bar, it's easier to set Bar as the DataContext of the parent container. A Binding without a Source will just use the DataContext by default, and DataContext flows through to child controls from the parent. So:
<StackPanel DataContext="{StaticResource Bar}">
<TextBox Text="{Binding Path=Foo}" />
<TextBox Text="{Binding Path=Fizz}" />
<TextBox Text="{Binding Path=Buzz}" />
</StackPanel>
All of the TextBoxes are still binding to properties on Bar, but they're doing it without setting it as a Source explicitly.
So let's have another look at the dialog you posted. It's giving you several options for the "source" of the ItemsSource binding. When you choose "DataContext", you're telling Visual Studio that the ItemsControl doesn't need to know the source - it'll pick it up from the DataContext of the parent container (maybe even the Window itself).
If you chose one of the other options (ElementName, RelativeSource or StaticResource) then you'd be setting the binding's source explicitly for that ItemsControl.
Once you've told it that it's binding to the DataContext, you'll need to drop into the "Path" section of the dialog and tell it which property to bind the items of the control to. In the end, the markup would look something like this (assuming it's a ListBox):
<ListBox ItemsSource="{Binding Path=Foos}" />
So the items in the ListBox are coming from a property called "Foos", and that property is on an object that's set in the DataContext somewhere higher in the logical tree (perhaps on the Window itself).
You rarely need to use the data context of a control outside of the control. The most common use case for setting DataContext(DataContext = this;) is within UserControl's code-behind to make all controls within the UserControl to bind to the control's properties.
When you use a ListBox, setting ItemsSource is sufficient, unless you are doing something funky.
This is a pretty good walkthrough: http://windowsclient.net/learn/video.aspx?v=315275
Specifically, you need to set the DataContext first to tell it where to look for the ItemsSource. The easiest way is to set this on the Window through the XAML:
<Window.DataContext>
<controllers:DownloadManager />
</Window.DataContext>

Why do I get Inconsistent Binding results

I have a control template with a toggle button. This ToggleButton has it's IsChecked property one way bound to a dependancy property. If i set the dependancy property explicitly the binding works.
The problem is that after I interact with the toggle button in the UI, the bindings don't update the IsChecked property if I set the dependency property explicitly.
I do have a work arround using TwoWay binding which works fine. My question is, why does it behave this way? Am I missing something? Is there a bug in the binding mechanism of Silverlight?
EDIT TO INCLUDE SNIPPET:
The binding in the ControlTemplate looks something like (could be replaced with TemplateBinding)
<ToggleButton x:Name="PlayPause" Grid.Column="0"
IsChecked="{Binding Paused, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}"
HorizontalAlignment="Center"
Width="50" Height="50"/>
The explicit setting of the dependency property is the fairly bog standard:
myComponent.Paused = true;
WPF deletes one way bindings when the target property (IsChecked in this case) is modified. Silverlight used to keep the binding when IsChecked was modified. If Paused was later set, this value would overwrite IsChecked as well.
According to you, it seems Silverlight reverted to WPF behavior. Oh well. Personally, I consider modifying a binded property a bug. If the properties are not meant to be in sync commanding may be a better solution.
You should use TwoWay binding
Make sure that the object that contains your Paused property supports INotifyPropertyChanged.
Make sure that the setter for Paused triggers the PropertyChanged event

Resources