I want to create animated button in Windows Phone 8 Silverlight using MVVM pattern.
This control should work like this:
When clicked, if it's value is correct, it would trigger rotating animation. When text wouldn't be visible(rotated 90 degrees around Y axis), I'd change text on button to something like "Yes!" and then it would rotate back to normal state.
In case the value would be incorrect, I'd change background to red, without rotation.
In WPF I could use DataTriggers, so I would look like this:
1)User Clicks button -> Command is executed
2a)If value is correct, i change in viewmodel some value, which triggers DataTrigger, which starts first animation rotating button 90 degrees
3a)End of animation triggers command, which change text value
4a)Text change Triggers second rotation, which at the beginning rotates button 180 degrees and then do normal 90 degrees rotation, so it looks like new text is on other site
2b)If value is incorrect I change some value to value triggering wrong value animation
But in windows phone silverlight there are no triggers in styles, so easiest way would be to just use code-behind, but I wanted to do it in MVVM.
Maybe someone have faced similar problem.
I'm currently thinking about using messages from MVVM Light toolkit, but I'm not sure, if it'll work
Edit:
Ok, thanks to Muhammad Saifullah's tip, I managed to make it work. I use button's command to send click to VM, next i use MVVM light Toolkit to send message to view to start the animation. Unfortunatly EventToCommand from MVVM light toolkit does not work for Storyboard, so I just Execute VM's command in code behind Completed event ant it changes the value and sends next messages.
You can bind command from your xaml to your VM. Below is an example how you bind command in MVVM Light.
For Button
<Button ....>
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<MvvmLight_Command:EventToCommand Command="{Binding Navigate}" CommandParameter="{Binding ElementName=btnClockin,Path=Tag}"></MvvmLight_Command:EventToCommand>
</i:EventTrigger>
</i:Interaction.Triggers>
Add following assembly references in page xaml
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:MvvmLight_Command="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras.WP8"
Command code in VM
/// <summary>
/// Gets the Navigate.
/// </summary>
public RelayCommand<object> Navigate
{
get
{
return _navigate
?? (_navigate = new RelayCommand<object>(
page =>
{
if (page.ToString() == "0")
MessageBox.Show("Comming Soon");
else
Messenger.Default.Send<NavigateCommand, MyPge33>(new NavigateCommand(page.ToString()));
}));
}
}
You can Bind commands on your story board in the similar way. But for starting the story board you can send message form your VM to your view.xaml.cs to start the storyboard.
Hope this helps.
Related
Since I cannot find any official documentation about it I need to ask this questions. Is there any way to animate grids on visibility change?
I have tried adding TransitionCollections to grids but it works only the first time that grid initialized.
I also tried this answer but it also wont work because Grid.Loaded event fires even if grid is collapsed.
You can use event Loaded(). Just add attributes in XAML
x:DeferLoadStrategy="Lazy" Visibility="Collapsed"
and element will be completely collapsed.
To load it use somewhere in C# code standart:
SomeHiddenElement.Visibility = Visibility.Visible;
This question already has an answer here:
NSTableView with +/- buttons like in System Preferences using only Interface Builder
(1 answer)
Closed 7 years ago.
I'm building an OSX app and want to create a set of controls similar to what's found at bottom of the standard Network Preferences configuration panel. I'm running into some layout problems that I wouldn't have expected.
These are my specific questions:
What contains the 3 buttons so there's similar shading all they way across the row where the buttons are positioned? In particular, what's causing the area without buttons to have shading?
How do you do this without getting a double border where the row of buttons meets up with the table?
I want to do this with an xib file. This may be incredibly simple, but I'm missing something I guess.
I find that if you make a button with style "Gradient" and type "Momentary Change", then it looks like the other buttons but does not respond to clicks, so you can use that as the area after the last button. (The NSMomentaryChangeButton is documented as changing the image and title when clicked, so if you don't use an image or title, nothing should change.)
If you check Refuses First Responder in the attributes inspector, then it will not be possible to highlight this blank button using Full Keyboard Access.
Ken Thomases also brings up the issue of the blank button being shown as a button to Accessibility. One can fix that by using a subclass of NSButtonCell that has just one method:
- (BOOL)accessibilityIsIgnored
{
return YES;
}
I think that's easier than writing a custom view.
As d00dle says, avoid double borders by slightly overlapping things.
Since you want the slack space to have the same background as the buttons, and since the buttons can change appearance from release to release of the OS, the best thing to do is to get the frameworks to draw it like it would the buttons.
Rather than using an actual button as JWWalker suggests, I have used a custom view that leverages NSButtonCell to draw the background. The advantage is that you can be sure there's no chance of getting undesirable behavior. For example, a button could get focus (for users who have All Controls selected in System Preferences > Keyboard > Shortcuts > Full Keyboard Access) so that the user could Tab to it. Accessibility will report the presence of the button through VoiceOver. Etc.
Configure the button cell just like the buttons (set buttonType and bezelStyle). In the view's -drawRect: call [buttonCell drawWithFrame:rect inView:self];, where rect is similar to the frames of the buttons. Since one way to avoid double borders is to make the buttons larger than the view's bounds, you may need to do the same for rect. For example, you might want to use NSInsetRect(self.bounds, -1, -1).
The buttons are buttons... This can be accomplished with a custom view drawing border and the background "shading".
To avoid the double border where the table and the custom view meet you simply align it so they overlap by 1 point (pixel) or avoid drawing the top border in your custom view.
I don't know of any standard object capable of doing this.
I have a requirement to create a button in a Windows 8.1 app which has an icon and a text label. The icon will be a symbol from Segoe UI Symbols and the text label will be Segoe UI Semibold at a smaller text size.
I want to be able to reuse the button in different places within the app, using different icons and text labels.
How show I go about this? I could create a button and then edit the ContentPresenter to have a horizontally oriented stack panel with two TextBlocks, but then how could I reuse this? And how could I change the text in the two different text blocks?
Should I create a separate custom control with separate dependency properties for each of the textblock strings? I'm interested in hearing what you would do.
thanks
Create a simple Style. To make it easy, I would base it off the standardized AppBarButton style. You can format it to whatever size you want (I have done something similar to make a larger button or one with text on the side).
Have the main icon simply be a ContentPresenter which binds to the Content using a TemplateBinding. Make sure to set the FontFamily to Segoe UI Symbol. Have the text label pull from AutomationProperties.Name, similar to how the AppBarButton style does.
Then, whenever you want to use this just do:
<Button Style="{StaticResource MyCustomButtonStyle}"
Content="" // Where "000" is replaced by the number of the icon you wish to use.
AutomationProperties.Name="Text Label"/>
This should be extensible and easily reproducible to whatever location you need. When copying over the AppBarButton style, I suggest removing the artificial size limits (specifically the width of the main content Grid). I do suggest either giving the Text Label a fixed size or having it pull its size from the specified parent Width, so that it will Wrap correctly.
Hope this helps and happy coding!
Are you desiring to create something like for an AppBar? Take a look at AppBarButton and the style/types it supports. In Windows 8.1 we added some things around SymbolIcon specifically. Since you basically want two pieces of 'content' for your style you'll have to re-purpose one property (unless you create a custom control which doesn't sound needed for this scenario). Using AutiomationProperties.Name for the visible label is a good idea because it will also help with accessibility by default for those users.
Investigate the style for AppBarButton to get you started.
I have searched for and found many posts that describe how to turn on the progress indicator. This is easy, 5 lines of code.
My problem is how do you then remove the indicator again after your async operation (usually on another thread somewhere) is finished? I am using an indeterminate indicator.
I have tried to call SystemTray.SetProgressIndicator(page, null) to remove the indicator and set everything back again to how it looked before I created the indicator, but I am left with a black (or white if light theme) bar at the top of the screen (where my pivot control should be occupying with a nice background picture).
I don't want to make the system tray invisible, because it was not invisible to start with I assume.
Are you using MVVM? If so, simply bind a variable in your View Model and change the value
<shell:SystemTray.ProgressIndicator>
<shell:ProgressIndicator IsIndeterminate="true" IsVisible="{Binding IsDataDownload}"/>
</shell:SystemTray.ProgressIndicator>
How can I find the component in a ScrollViewer that handles the RequestBringIntoView event?
It isn't exposed on the two ScrollBar parts (not directly, anyway).
Thanks for any pointers...
UPDATE: Related: Can I get the ScrollContentPresenter part of the ScrollViewer? How?
Thanks --
Bigger picture:
We have a large Canvas contained in a ScrollViewer. At runtime, an arbitrary number of UserControls (I'll call them 'Blobs') are added to the canvas from the db. Their position and content come from the db. A user can 'select' a blob by clicking on it, and its appearance changes to indicate it is selected.
If the user uses a scrollbar to move the selected blob out of view, then clicks on another blob, the Canvas is scrolled so the previously-out-of-view blob is in view again. I assume this is due to some object raising the RequestBringIntoView, and the ScrollViewer is handling it.
Hope this makes sense...
Yet more info:
Added a handler (sb_ValueChanged) to the Scrollviewer's scrollbar ValueChanged event. Here's the stack from the mouse click that precipitates the scrolling:
OurControl.sb_ValueChanged() System.Windows.dll!System.Windows.Controls.Primitives.RangeBase.OnValueChanged() System.Windows.dll!System.Windows.Controls.Primitives.ScrollBar.OnValueChanged() System.Windows.dll!System.Windows.Controls.Primitives.RangeBase.OnValuePropertyChanged()
System.Windows.dll!System.Windows.DependencyObject.RaisePropertyChangeNotifications()
System.Windows.dll!System.Windows.DependencyObject.UpdateEffectiveValue()
System.Windows.dll!System.Windows.DependencyObject.SetValueInternal()
System.Windows.dll!System.Windows.DependencyObject.SetValue()
System.Windows.dll!System.Windows.Controls.ScrollViewer.InvalidateScrollInfo() System.Windows.dll!System.Windows.Controls.ScrollContentPresenter.VerifyScrollData()
System.Windows.dll!System.Windows.Controls.ScrollContentPresenter.ArrangeOverride()
System.Windows.dll!System.Windows.FrameworkElement.ArrangeOverride()
If only I could find out what the FrameworkElement that starts the mischief actually is...
Sorry... it doesn't seems to exist like it does in WPF. Check this link for a handy solution.
Update: Ok... for this you might need to walk the visual tree and some sort of recursive search need to be done. However, assuming you are using the default template for the scrollviewer as seen here, you can directly ask for the ScrollContentPresenter with something like this:
var BorderChild = VisualTreeHelper.GetChild(MyScrollViewer, 0);
var GridChild = VisualTreeHelper.GetChild(BorderChild, 0);
var ScrollContentPresenterChild = VisualTreeHelper.GetChild(GridChild, 0);