Silverlight SelectedRow styling - c#

I had an issue changing the foreground color for selected items on Datagrids.
I found a fix that works, but it is expensive when using Datagrids with a lot of items/data and it also complicates the design tree a bit more.
This is my Coding:
...<VisualState x:Name="NormalSelected">
<Storyboard>
<DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="BackgroundRectangle"/>
<ObjectAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000" Storyboard.TargetName="contentControl" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="00:00:00" Value="Yellow"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>...
...
...<ContentControl x:Name="contentControl" Foreground="Green">
<sdk:DataGridCellsPresenter x:Name="CellsPresenter" Grid.Column="1" sdk:DataGridFrozenGrid.IsFrozen="True"/>
</ContentControl>...
This is the only way I could think of doing it in XAML. I don't know if there are any other ways of doing it in xaml rather than rapping the CellPresenter with a control everytime?

Related

VisualState, StoryBoard, Instant change of color (without animation)

my task seemed to me as something easy (WinRT).
All I want is to change color of Rectangle depending on state.
I know how to do it in a "cool" animated way.
The thing is that I just want my color to be changed immediately without any animation.
This is a standard, cool way:
<VisualState x:Name="UnFocused">
<Storyboard Duration="1">
<ColorAnimation To="{ThemeResource LightGrayColor}"
Storyboard.TargetName="borderBrush"
Storyboard.TargetProperty="Color"/>
</Storyboard>
</VisualState>
I thought that if I change Duration to zero then the change will be instant.
It does not work this way, color did not change at all.
So I tried "0:0:0.1" but it did not change color either.
So...
What is the current approach to change color in instant using VisualState functionality?
Thank you :-)
I don't know whether WinRT has some restrictions. At least I would also have expected that zero works fine. But you have some more options and still being cool:
<ObjectAnimationUsingKeyFrames Duration="00:00:00"
Storyboard.TargetName="borderBrush"
Storyboard.TargetProperty="Color">
<DiscreteObjectKeyFrame KeyTime="00:00:00">
<DiscreteObjectKeyFrame.Value>
<SolidColorBrush Color="{ThemeResource LightGrayColor}"/>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
or
<ColorAnimationUsingKeyFrames Storyboard.TargetName="borderBrush"
Storyboard.TargetProperty="Color">
<EasingColorKeyFrame KeyTime="0"
Value="{ThemeResource LightGrayColor}" />
</ColorAnimationUsingKeyFrames>
Turning #Jacek-Wojcik's comment into an answer:
Don't set a duration on the storyboard, set it on the ColorAnimation instead:
<VisualState x:Name="UnFocused">
<Storyboard >
<ColorAnimation Duration="0" To="{ThemeResource LightGrayColor}"
Storyboard.TargetName="borderBrush"
Storyboard.TargetProperty="Color"/>
</Storyboard>
</VisualState>

WP8.1 - How can I show a Flyout at the bottom of the page?

I'm building an app for WP8.1 and I need a custom keyboard to enter some particular character into a TextBox. I decided to use a Flyout to display a User Control with a series of buttons, so that the user will be able to tap on each button to add a new character.
Everything works fine, but the problem is that I can't find a way to display the Flyout in the second half of the page or at the bottom of the page.
This is the method I use to display it:
private void Button_Click(object sender, RoutedEventArgs e)
{
var flyout = new Flyout();
var tb = new CustomKeyboard();
flyout.Placement = FlyoutPlacementMode.Bottom;
flyout.ShowAt(Window.Current.Content as FrameworkElement);
}
This works, but even though I selected the bottom Placement, the Flyout is displayed at the top of my page. I also tried to create a grid with two rows, with another Grid in the second row, and to call the flyout with that inner grid as FrameworkElement, but it still gets displayed at the top of my page, I don't know why.
Am I missing anything? Is there a way to display that flyout at the bottom, or is there another control/class I can use to do that?
Thanks!
Sergio
EDIT: I ended up using a grid and some Storyboards as suggested :)
<!--Transitions-->
<Page.Resources>
<Storyboard x:Name="tastieraInDestra">
<DoubleAnimation Storyboard.TargetName="tastiera" Storyboard.TargetProperty="Opacity"
From="0.0" To="1.0" Duration="0:0:0.3"/>
<DoubleAnimation Storyboard.TargetName="SlideIn" Storyboard.TargetProperty="X"
From="750" To="0" Duration="0:0:0.4"/>
</Storyboard>
<Storyboard x:Name="tastieraInSinistra">
<DoubleAnimation Storyboard.TargetName="tastiera" Storyboard.TargetProperty="Opacity"
From="0.0" To="1.0" Duration="0:0:0.3"/>
<DoubleAnimation Storyboard.TargetName="SlideIn" Storyboard.TargetProperty="X"
From="-750" To="0" Duration="0:0:0.4"/>
</Storyboard>
<Storyboard x:Name="tastieraOutDestra">
<DoubleAnimation Storyboard.TargetName="tastiera" Storyboard.TargetProperty="Opacity"
From="1.0" To="0.0" Duration="0:0:0.3"/>
<DoubleAnimation Storyboard.TargetName="SlideIn" Storyboard.TargetProperty="X"
From="0" To="750" Duration="0:0:0.4"/>
</Storyboard>
<Storyboard x:Name="tastieraOutSinistra">
<DoubleAnimation Storyboard.TargetName="tastiera" Storyboard.TargetProperty="Opacity"
From="1.0" To="0.0" Duration="0:0:0.3"/>
<DoubleAnimation Storyboard.TargetName="SlideIn" Storyboard.TargetProperty="X"
From="0" To="-750" Duration="0:0:0.4"/>
</Storyboard>
</Page.Resources>
I control these Storyboards inside the pivot.SelectionChanged method, and I added everything inside the grid in the main page. The only downside is that now my main page xaml file is getting a bit crowded as I have all my UI in one page, but it works fine :D
Thanks!

Image fade doubleanimation

I'm trying to achive a fade out effect on an image in wpf and c#
<Image.Triggers>
<EventTrigger RoutedEvent="Image.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="imgSlot1"
Storyboard.TargetProperty="Opacity"
From="1.0" To="0.0" Duration="0:0:1"
AutoReverse="True" RepeatBehavior="Forever"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
With this code i see my image flashing,and that's ok but why if i change RepeatBehavior to "1x" or "0:0:1" and AutoReverse to "False" (i have to create a single effet of fade out on my image) nothing works?
I was a bit surprised when you said nothing works when you set AutoReverse="False" and RepeatBehavior="1x", so I tried it, and a single fade out works fine. Here is the xaml:
<Image.Triggers>
<EventTrigger RoutedEvent="Image.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="imgSlot1"
Storyboard.TargetProperty="Opacity"
From="1.0" To="0.0" Duration="0:0:1"
AutoReverse="False" RepeatBehavior="1x"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Image.Triggers>
However, I am not sure you want that to occur on the Image.Loaded event. And remember you can easily control that from C# or VB, even without a storyboard, similar to the following:
DoubleAnimation fadeoutAnimation = new DoubleAnimation();
fadeoutAnimation.Duration = TimeSpan.FromSeconds(1.0d);
fadeoutAnimation.From = 1.0d;
fadeoutAnimation.To = 0.0d;
imgSlot1.BeginAnimation(Image.OpacityProperty, fadeoutAnimation);
Hope this helps!

Storyboard DoubleAnimation Does not work with StackPanel Height Property

I'm trying to use DoubleAnimation to change the Height property of a StackPanel. The code does not throw any exception. But the animation does not work.
<StackPanel x:Name="FlyoutContent">
<StackPanel.Resources>
<Storyboard x:Name="HideStackPanel">
<DoubleAnimation Storyboard.TargetName="ChangePasswordPanel" Storyboard.TargetProperty="Height" From="190" To="0" Duration="0:0:1">
<DoubleAnimation.EasingFunction>
<PowerEase EasingMode="EaseIn"></PowerEase>
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
</Storyboard>
<Storyboard x:Name="ShowStackPanel">
<DoubleAnimation Storyboard.TargetName="ChangePasswordPanel" Storyboard.TargetProperty="Height" From="0" To="190" Duration="0:0:1">
<DoubleAnimation.EasingFunction>
<PowerEase EasingMode="EaseIn"></PowerEase>
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
</Storyboard>
</StackPanel.Resources>
<TextBlock Margin="0, 20, 0, 0" FontWeight="Bold" Text="Change Current Password" TextWrapping="Wrap" Style="{StaticResource BasicTextStyle}" HorizontalAlignment="Left" IsTapEnabled="True" Tapped="ChangePasswordHeader_Tapped"/>
<StackPanel x:Name="ChangePasswordPanel" Margin="0, 5, 0, 0" Height="0">
C# Event Handler
private void ChangePasswordHeader_Tapped(object sender, TappedRoutedEventArgs e)
{
if (ChangePasswordPanel.Height == 0)
{
ShowStackPanel.Begin();
}
else
{
HideStackPanel.Begin();
}
}
It does hit ChangePasswordHeader_Tapped event handler and execute ShowStackPanel.Begin or HideStackPanel.Begin statement as expected. But it does not have any impact on the output. The Height of the StackPanel just stays at 0.
Any idea on what's happening??
I figured it out myself. All I had to do was to Enable Dependent Animation (EnableDependentAnimation) on the DoubleAnimation as this animation affects the layout. And then it worked perfectly.
<Storyboard x:Name="HideChangePasswordPanel">
<DoubleAnimation EnableDependentAnimation="True" Storyboard.TargetName="ChangePasswordPanel" Storyboard.TargetProperty="Height" From="190" To="0" Duration="0:0:0.2">
<DoubleAnimation.EasingFunction>
<PowerEase EasingMode="EaseIn"></PowerEase>
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
</Storyboard>
<Storyboard x:Name="ShowChangePasswordPanel">
<DoubleAnimation EnableDependentAnimation="True" Storyboard.TargetName="ChangePasswordPanel" Storyboard.TargetProperty="Height" From="0" To="190" Duration="0:0:0.2">
<DoubleAnimation.EasingFunction>
<PowerEase EasingMode="EaseIn"></PowerEase>
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
</Storyboard>
Hope it saves someone some time!
The easiest way to animate the size of a UI component generally in XAML (and Silverlight/WPF) is to use a RenderTransform. Depending on the layout, you may need to do a few tricks, but for a quick animation, it generally looks very nice.
<Storyboard x:Name="Storyboard1">
<DoubleAnimation Duration="0:0:2"
To="0"
Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.ScaleY)"
Storyboard.TargetName="StatListView" d:IsOptimized="True"/>
<DoubleAnimation Duration="0:0:2"
To="0"
Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)"
Storyboard.TargetName="StatListView" d:IsOptimized="True"/>
</Storyboard>
The stack panel takes its height from the combined height of its contents. Setting the height explicitly has no meaning.
You need to change the height/visibility of the stack panel's contents.

Programmatic state changes not working in Silverlight

I'm trying to get states to change with the visual state manager through code.
I am using:
Microsoft.Expression.Interactivity.Core.ExtendedVisualStateManager.GoToElementState(this.LayoutRoot, "stateRegistration", true);
But it doesn't seem to want to work, I have create an event handler and also a listener but it there's no state changed when using that code.
Can anyone help me out.
XAML CODE (Code Snippet):
<Grid x:Name="LayoutRoot" Width="897" Height="699">
<VisualStateManager.VisualStateGroups>
<VisualState x:Name="stateRegistration">
<Storyboard>
<DoubleAnimation Duration="0" To="870" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateX)" Storyboard.TargetName="RegisterContent" d:IsOptimized="True"/>
<DoubleAnimation Duration="0" To="880" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateX)" Storyboard.TargetName="HomeContent" d:IsOptimized="True"/>
<DoubleAnimation Duration="0" To="0" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateX)" Storyboard.TargetName="btnRegRegister" d:IsOptimized="True"/>
<DoubleAnimation Duration="0" To="-10" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)" Storyboard.TargetName="btnRegRegister" d:IsOptimized="True"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Grid>
Thanks.
There is strange behavior with the VisualStateManager: its states must be situated not in the control, but in the child control.
It means, that the GoToState method should be called with the this parameter instead of the this.LayoutRoot parameter, but definitions of state groups must be situated inside the Grid:
VisualStateManager.GoToState(this, "stateRegistration", true);
I don't know where to get the ExtendedVisualStateManager class so I use the default one.
Also if any animation of the state storyboard fails - all animations are cancelled. So try this code sample with two animations, it must work:
<Grid x:Name="LayoutRoot" Width="897" Height="699">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup>
<VisualState x:Name="stateRegistration">
<Storyboard>
<DoubleAnimation Duration="0" To="0" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateX)" Storyboard.TargetName="btnRegRegister" d:IsOptimized="True"/>
<DoubleAnimation Duration="0" To="-10" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)" Storyboard.TargetName="btnRegRegister" d:IsOptimized="True"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Button x:Name="btnRegRegister" Content="Some button" Click="btnRegRegister_Click" VerticalAlignment="Center" HorizontalAlignment="Center">
<Button.RenderTransform>
<CompositeTransform TranslateX="0" TranslateY="0" />
</Button.RenderTransform>
</Button>
</Grid>

Categories

Resources