Execute storyboard when databound property changes - silverlight

Just this. I want that when the databound property Text of a TextBlock for example changes, an animation is performed to give some feedback to the user. How can this be done?? thanks!

I found a way to do it using a PropertyChangedTrigger
<Interactivity:Interaction.Triggers>
<ec:PropertyChangedTrigger Binding="{Binding KnownMeaning}" >
<eim:ControlStoryboardAction Storyboard="StaticResource Storyboard2}"/>
</ec:PropertyChangedTrigger>
</Interactivity:Interaction.Triggers>
There may be a more elegant solution, but I think this is pretty straightforward

You can simply add event to ViewModel and start animation (Storyboard.Begin) in code-behind. Or even do it without extra event by adding handler of ViewModel.PropertyChanged in code-behind.
More advanced options are listed here:
Re: How to Annimate (Storyboard.Begin() ) in MVVM.

Related

Q: Update viewmodel property from a listview binded textbox

i've got a textbox which text is binded to a listview selecteditem as follows:
<TextBox x:Name="txtAdditional" Width="300" Text="{Binding ElementName=lstPersons, Path=SelectedItem.Additional, Mode=OneWay}" />
Now i like to implement a mechanism to add new items to the listview using this textbox to get the actual data. So i would like to bind the text of the textbox to a property of the viewmodel so it can be processed by a command.
So it the textboxes text has to be binded to the listviews selecteditem and additionally to a property of my viewmodel.
I've searched around and found some approaches but i can't help to think that there should be some simpler mechanism to archive this goal.
What I found by now:
Using MultiBindung with some kind of ValueConverter? So it seems to me that this is primary for displaying and not for updating a viewmodels property.
The use of some selfdefined custom control?
The use of an BindingProxy with in- and out-dependencyproperties like in Impossible WPF Part 1: Binding Properties?
Is there another, simpler solution to this or would i have to use one of those above?
And if one should use one of those approaches, which one whould you choose?
I can't help but thinking that this issue hasn't been given some thoughts already, using an mvvm pattern?! ;-)
yes thanks to the hint from BionicCode.
We, or better I should have to think the MVVM concept out. Of course no - or at least as little code behind as possible.
I added the property "selectedPerson" to my viewmodel and bound the SelectedItem of the listview to this property. So the object related properties were at hand directly through the "selected" object in my viewmodel and there was no need anymore to access the textbox content at all.
Thanks to BionicCode for the hint!

Silverlight: ViewModel trigger function in code behind

I have a bit of a problem with my Silverlight application, and my usage of the MVVM pattern.
In my View I have a DataGrid. The ItemsSource would normaly be bound to the ViewModel, but in my specific case I need the columns to be dynamic and my items collection consists of a Dictionary for each item, so I have no class properties to show. My solution was to generate all this in codebehind, since the actual design of the DataGrid has nothing to do with my ViewModel. This was the only solution I could think of since the columns can't be databound.
I have got all of this to work. My problem is that I'm using RIA and the view has no idea when the items collection has finished loading. I tried my design out by putting an ordinary button on the view to trigger the codebehind function, but obviously this solution is no good. I need my codebehind function to run as soon as my item collection has finished loading.
Can I make my codebehind listen to the ViewModel?
I have a feeling that you are messing up things somewhere.
For your question I think you can solve it by having an event in the ViewModel.
Subscribe to that event in your view's view_Loaded event and call the codebehind function in the handler.
I would recommend you to recheck your design and to see if this is really necessary.
I understand what you mean, we once had to do the same thing generating random columns which is a PIA in silverlight because you would need some kind of object that has a dynamic set of properties.
I see you've found the Dictionary solution. What I would suggest, which isn't per sé the cleanest solution but it is cleaner then putting the stuff in the code behind, is to add this in a converter. Then bind the collection to the itemssource of an itemscontrol and then when the list propertychanged is raised you assemble the datagrid in the converter.
small example:
<ItemsControl Grid.Row="1" ItemsSource="{Binding theListOfEntities, Converter={StaticResource theconverter}}"/>

WPF: How do I bind to an ICommand defined in a control?

My control has a property that returns an ICommand object. Using XAML, how to I bind a button to it?
Without knowing anything about the relation of the two I would use element binding. E.g.
<YourControl x:Name="CmdSrc" />
<Button Command={Binding ElementName=CmdSrc, Path=CmdProperty} />
You should think about the approach that a control provides a command. It's seems to me some kind of weird. ;)
Regards
EDIT
Ah ok, it was just a hint. Just in case you didn't think about it.
Here is another way to bind your command. I've to admit that I didn't test it. But I think the following should work too.
When the Button is in the control you could also use relative binding.
<YourControl>
<Button Command={Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type YourControl}}, Path=CmdProperty} />
</YourControl>
Then you don't need a name for the control. I'm avoiding names when ever I can to prevent dirty workarounds in code behind.
Yes, I know it some kind of paranoid. ;)

Silverlight Listbox firing MouseRightButtonDown, but not MouseLeftButtonDown

I have this problem in a bigger Project...... so I set up a 'Testpoject' as Proof of Concept:
New Silverlight-Application
Add Listbox
Fill listbox with a few Checkboxes
Register listBox1_MouseLeftButtonDown
register listBox1_MouseRightButtonDown
You will see, that the listBox1_MouseLeftButtonDown won't fire under any circumstances....
listBox1_MouseRightButtonDown however fires just fine.
I tried using a custom Class deriving from ListBox and overriding, assuming something in the ListBox Class was setting e.Handled = false, but this did not change the behaviour, either.
Any Ideas on why this happens and how to fix?
(This problem also stops the 'parent'-control from receiving the Click-Event... so the Event-passing is broke)
:edit:
I fixed my problem with a workaround... so an answer is not required anymore. Just if somebody feels like figuring out why this is happening for the sake of it ;)
This seems to answer your question. To quote:
That's because ListBoxItem internally handles this event as well as the MouseLeftButtonDown event (halting the bubbling) to implement item selection.
The solution is to add the event handler in the code-behind file. From the article:
Although setting the RoutedEventArgs parameter's Handled property to true in a routed event handler appears to stop the tunneling or bubbling, individual handlers further up or down the tree can opt to receive the events anyway! This can only be done from procedural code, using an overload of AddHandler that adds a Boolean handledEventsToo parameter.
See the caveat at the end though.
This is by design. If you check the framework code, you'll see that the ListBoxItem sets the Handled property to true.
I had this same exact problem, so in my ListBoxItem.ItemTemplate, I added the event handler in my content.
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" MouseLeftButtonDown="StackPanel_MouseLeftButtonDown">
... other controls ...
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>

MVVM What is the way of updating a UI after a command?

I'm learning MVVM through a project and I got stuck on something simple.
I have a Button that updates a ListView. I have a command in the ViewModel that make the right things but I want to select the new row and get the focus on a TextBox after I click the Button.
The question is: How do I update my UI after executing a command?
If I need to change my windows Title when an operation have been made, I use a property on the ViewModel that is binded to the Window's title and it's changed when I need it but, I don't know how to get focus on a control when a command has been executed.
Thank you.
To select the new row, add a new property to your ViewModel ("SelectedItem" for instance), and bind the ListView's SelectedItem property to it :
<ListView ItemsSource="{Binding Items}" SelectedItem="{Binding SelectedItem}">...
In the ViewModel, you just have to assign the new item to the SelectedItem property
To focus the TextBox, Mike's idea seems a good one
You could make an attached behavior. I'd suggest using the new Blend behavior framework, ie TriggerAction that contained this custom logic.
For your attached behavior you put on the button, give it a DP for an ICommand and maybe a DP of a ListView type.
On the "protected override void Invoke(object parameter)" of your TriggerAction, execute your ICommand, then you have reference to your ListView. Here you can do your custom code on it, like setting focus.
Your XAML may look something like this:
<Button>
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<Behaviors:CustomBehavior Command="CommandName" ListView="{Binding ElementName=myListView}" />
</i:EventTrigger>
</i:Interaction.Triggers>
<Button/>
I suggest looking at Mike Brown's ExecuteCommandAction behavior (download here), it's about almost 1/2 of what you need.
What about setting focus to the control in the code behind: textBox.Focus()
I consider everything you mention in your question to be GUI logic so I would add a Click event to the button to handle stuff that needs to happend in the GUI.
Hope this helps.
I think you need to use the Mediator pattern. Please see this:
Josh Smith's Mediator Prototype for WPF Apps
This is generally used in communicating with the View from the View-Model. Hope this helps.
In your case you need some way that the ViewModel notifies the View that it should set the focus on a specific control.
This could be done with an IView interface. The view implements this interface and the ViewModel can call a method of the View over this interface. This way you have still the View and ViewModel decoupled of each other.
How this can be done is shown here:
WPF Application Framework (WAF)
http://waf.codeplex.com

Resources