I have a listview in a page specific to the WP8.1 portion of the solution, with a standard ObservableCollection as the itemssource. I would like to highlight the selected item, which for the moment is using a datatemplate of just a textblock. It seems this feature is supported in the base WP8.1 control, only in the W8.1 version.
Following the solution presented here; How to change color of the selected ListView item [WP8.1]
I managed to get it to highlight with a specified colour, but I'd really like to be able to bind to the phone's accent colour, which I'm certain that I was able to bind to this in WP8.0, but the resource isn't available in the page in the universal app.
for the moment I have replaced the direct colour specification of 'red' with
<ColorAnimation Duration="0" Storyboard.TargetName="myback" Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)" To="{ThemeResource PhoneChromeColor}"/>
which works to highlight the item, but obviously not the colour I want.
Can I get access to the PhoneAccentBrush in the xaml? Is there a better way to achieve my goal? I am not a professional developer, so some 'user friendly' guidance would be most helpful. Thanks.
The To property of ColorAnimation expects an object of type Color. PhoneAccentBrush is of the SolidColorBrush type.
Here are two suggestions (I haven't tested them, but I think they should work):
Objects of the SolidColorBrush type have a property Color of type Color which you can use like this {Binding Color, Source={StaticResource PhoneColorBrush}}.
You can also use the PhoneAccentColor static resource, which is basically the color of the PhoneAccentBrush brush, like this: {StaticResource PhoneAccentColor}.
Also, if you're not really animating the color, you can just change the whole brush with something like this:
<ObjectAnimationUsingKeyFrames Duration="0" Storyboard.TargetName="myback" Storyboard.TargetProperty="(Border.Background)">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneAccentBrush}"/>
</ObjectAnimationUsingKeyFrames>
I hope some of these would work for you! :)
I want to start by agreeing that #Scoregraphic is correct. Your error message is something that is unique to you. That being said, you should know that the accent brush on Windows is always purple. Using the accent brush has little value because of this.
You can overcome this with device-specific styling. This means you can use accent brush in your Phone app but in your Windows app you add whatever logic you want to have a color that makes sense.
I discuss device-specific styling more here:
http://channel9.msdn.com/series/Developing-Universal-Windows-Apps-with-C-and-XAML/03#time=27m00s
Best of luck!
The PhoneAccentBrush is available through {StaticResource PhoneAccentBrush} in the XAML
Related
I am writing a UWP WinRT app in C#. I found the very useful BitmapIcon class and use it for a grid of icons on the main page of my app. The BitmapIcon class has a Foreground brush that can be used to override the color of the original bitmap which is handy for when something controls the icon colors separate from the picture itself (like a server dictating that an icon be red to show that it's important).
I am using a storyboard animation to change the icon colors (for a flashing effect that I know is not liked these days but I am forced to do it). Here's the code:
ColorAnimationUsingKeyFrames colorAnimation = new ColorAnimationUsingKeyFrames();
colorAnimation.Duration = TimeSpan.FromSeconds( 3 );
colorAnimation.EnableDependentAnimation = true;
IconImage.Foreground = new SolidColorBrush( iconColor ?? AppSettings.appColor );
DiscreteColorKeyFrame key1 = new DiscreteColorKeyFrame();
key1.Value = finishColor;
key1.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromSeconds( 0 ) );
colorAnimation.KeyFrames.Add( key1 );
LinearColorKeyFrame key2 = new LinearColorKeyFrame();
key2.Value = startColor;
key2.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromSeconds( 3.0 ) );
colorAnimation.KeyFrames.Add( key2 );
colorAnimation.RepeatBehavior = RepeatBehavior.Forever;
Storyboard.SetTargetProperty( colorAnimation, "(BitmapIcon.Foreground).Color" );
Storyboard.SetTarget( colorAnimation, IconImage );
// Create a storyboard to apply the animation.
//Storyboard myStoryboard = new Storyboard();
animationStoryboard.Children.Add( colorAnimation );
animationStoryboard.Duration = colorAnimation.Duration;
animationStoryboard.RepeatBehavior = colorAnimation.RepeatBehavior;
animationStoryboard.Begin();
This seems to somewhat work. I get no exceptions and the colors do change. The problem is that the changes do not show up in the window. If I resize the app window, the colors can be seen to change as I drag the edge of the window. When I stop, they stop showing a change but the change appears to stil lbe happening in the background invisibly. I can tell that the numbers are changing in the background because of the jump in colors that happen when I stop changing the size of the window for a moment.
It's been a while since I worked on C# UWP WinRT code and I think I'm missing some sort of attribute or property of the Imageicon object, it's Foreground SolidColorBrush, or the Color associated with the SolidColorBrush.
Elsewhere in my code, I use similar methods to animate an opening and closing sidebar on the window. That works and the animation is smooth, as expected.
I need to figure out why the color change seems to happen but without the UI getting updated constantly.
How can I get the UI to update when animating a color change
I could reproduce this issue, and I have discussed with team, it is a bug, I reported it to related team just now. And you could also post this with Windows feed back hub app.
If I receive any info about this, I will update below. thx!
Update
This isn’t ideal, as it involves 2 animations and 2 separate BitmapIcons, we may be able to tweak it to our liking by only using 1 Animation and having a static image behind the BitmapIcon. Please check the following code.
<Grid>
<BitmapIcon
x:Name="IconImageOne"
Foreground="Red"
UriSource="ms-appx:///Assets/StoreLogo.png">
<BitmapIcon.Resources>
<Storyboard x:Name="animationStoryboard">
<DoubleAnimation
AutoReverse="True"
RepeatBehavior="Forever"
Storyboard.TargetName="IconImageOne"
Storyboard.TargetProperty="Opacity"
From="1.0"
To="0.0"
Duration="0:0:3" />
<DoubleAnimation
AutoReverse="True"
RepeatBehavior="Forever"
Storyboard.TargetName="IconImageTwo"
Storyboard.TargetProperty="Opacity"
From="0.0"
To="1.0"
Duration="0:0:3" />
</Storyboard>
</BitmapIcon.Resources>
</BitmapIcon>
<BitmapIcon
x:Name="IconImageTwo"
Foreground="Green"
Tapped="IconImage_Tapped"
UriSource="ms-appx:///Assets/StoreLogo.png" />
</Grid>
Code behind
private void StatAnimation()
{
animationStoryboard.Begin();
}
private void IconImage_Tapped(object sender, TappedRoutedEventArgs e)
{
StatAnimation();
}
I'm posting this untested answer because I think it is a viable option and might work as well as the workaround that I used (and mentioned as a comment on my original post)...
Set up the code to animate the color in case that ever works in the future. Then also add an animation to alter the opacity of the BitmapIcon between 1.0 and 0.99999, or some other similar values. The Opacity change should cause a refresh of the view/screen while not actually changing the opacity enough for the user to see it. The color change will then be visible because of the opacity update.
I have not tested this since I had to move on after using the two-Bitmapicon workaround.
I have a number of scenarios where I am doing simple WPF storyboard animations as such.
<Storyboard x:Key="MyTextBlockStoryBoard" RepeatBehavior="Forever">
<DoubleAnimation AutoReverse="True"
Duration="0:0:8"
From="0.0"
Storyboard.TargetName="MyTextBlock"
Storyboard.TargetProperty="(Canvas.Left)"
To="500.0" />
</Storyboard>
However I need to be able to set the To value in this animation to a dynamic value which is equivalent to UserControl.ActualWidth - MyTextBlock.ActualWidth. I understand that obviously I can easily create a Storyboard as above programmatically but I am hoping to stay inside Xaml world.
My inkling is that the only way I can achieve this is through implementing my own IValueConverter but I am hoping that there might be a easier way to achieve my desired output?
suppose you want to animate something, Which one is better to use by performance?
using Storyboards in XAML ?
OR
classes like DoubleAnimation in Media.Animation in Code-Behind?
As said previously, Storyboards are not Animation, thus you can't compare them.
I must suppose that your question is about creating a DoubleAnimation in code behind or in XAML like that:
<Storyboard>
<DoubleAnimation />
</Storyboard>
Thus, your question is pretty similar to: is there a performance difference if I create my object in XAML or in C# code behind.
And my answer is...You should really don't care, at first. To quote a certain Kent Beck: Make it works, make it clean, make it fast. In WPF, to make it clean, you should implement MVVM to have a clear separation of concern. And an animation is clearly an UI concern, so it should be design in the view: your xaml file.
Now if I try to anwser your question anyway, there is almost no performance difference, because a DoubleAnimation object is created eventually in any case.
So do it in XAML, it will be better for the architecture of your software.
Let me conclude by this: if you really have performance constraints for your application, WPF is probably a poor choice anyway as it was not designed to be efficient. The real power of WPF is to allow this clear separation of concern.
1st thing is StoryBoard is not an animation. If you follow below example:
<Storyboard x:Name="myStoryboard">
<DoubleAnimation
Storyboard.TargetName="MyAnimatedRectangle"
Storyboard.TargetProperty="Opacity"
From="1.0" To="0.0" Duration="0:0:1"
AutoReverse="True" RepeatBehavior="Forever" />
</Storyboard>
Here animation is created and applied it to the rectangle's Opacity property using StoryBoard
More information is here
I've spent about the entire day looking at examples of XAML storyboarding, but WinRT/Windows8 apps doesn't work the same way WPF does (At least I think), and I'm all confused.
All I want is a button that moves 100px left and 100px up when clicked. I'm having the hardest time figuring this out, and I know that once I get something I want working, I'll be able to work from there.
Also, if anyone can teach me how to use "Storyboard.TargetProperty" That'd be amazing.
<Rectangle
Name="Rectangle01"
Height="100"
Width="100"
Fill="Red">
<Rectangle.Resources>
<Storyboard x:Name="myboard">
<DoubleAnimation
Storyboard.TargetName="Rectangle01"
Storyboard.TargetProperty="Width"
From="100" To="3600" Duration="0:0:6" />
</Storyboard>
</Rectangle.Resources>
</Rectangle>
Here's an example of something I tried doing just to mess around with storyboards. This didn't throw an error until I tried to execute it, but it still doesn't work.
So yea, WRT is a little different in some ways, but many not.
What you're wanting to do is move your Button around, up and left so logically on an X and Y axis right? So in my mind, I think RenderTransform/TranslateTransform to leverage the X and Y like;
<Button Click="StartTheMove">
<Button.RenderTransform>
<TranslateTransform x:Name="MoveFoo"/>
</Button.RenderTransform>
</Button>
So now we have MoveFoo and setup our Transform, and since the only default Routed.Event I know of for WRT is Loaded we can't do that, so tie into the Click handler with StartTheMove like;
private void StartTheMove(object sender, RoutedEventArgs e)
{
MoveTheButton.Begin();
}
So now we've got our handler and we want to fire off MoveTheButton which will be your actual storyboard set as a resource somewhere in say your window.resources or whatever like;
<Storyboard x:Name="MoveTheButton">
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="MoveFoo"
Storyboard.TargetProperty="Y">
<SplineDoubleKeyFrame KeyTime="0:0:1.25" Value="100" />
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="MoveFoo"
Storyboard.TargetProperty="X">
<SplineDoubleKeyFrame KeyTime="0:0:1.25" Value="-100" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
So once we hit our Storyboard it's then going to go and tell our Transform that we want the properties of X and Y to get some new properties declared (here's your Storyboard.TargetProperty coming in to join the fun) and we're going to set the values to those two properties to something other than what they already are and basically tell it we want it to move 100px up on the Y (up) and -100px on the X (left) of our 2d axis. Which you'll also prob want to play with the keytimes for however fast/slow you want the effect to happen.
While I didn't have time to test this and am kind of just adhoc throwing it together before I leave the office for the day, we've all been where you are and hopefully it helps. You should also be able to add the interaction behaviors to kind of leverage the same type of event triggers you're probably more used to (see tutorials) and handle your event that way to ditch your handler code behind.
However hopefully this helps, if not I'll see it again in the morning and will take another stab at it. Cheers!
I want to change the color of a SolidColorBrush in a xaml, from c# code, while the app is running.
(This is a Pie chart from WinRT XAML Toolkit, and I want change the color of the slices.)
<charting:Chart.Palette>
<charting:ResourceDictionaryCollection>
<ResourceDictionary>
<SolidColorBrush x:Key="MyBrush" Color="#4586d8"/>
<Style x:Key="DataPointStyle" TargetType="Control">
<Setter Property="Background" Value="{StaticResource MyBrush}"/>
</Style>
</ResourceDictionary>
</charting:ResourceDictionaryCollection>
</charting:Chart.Palette>
Since there is no DynamicResource in Win8 apps, this is how i tried to set with no success:
Color yellow = Color.FromArgb(0xff, 0xff, 0xb9, 0x01);
Application.Current.Resources["MyBrush"] = new SolidColorBrush(yellow);
How could I set the color of the resource?
I think in WPF DynamicResource would basically create a new instance every time it's requested and would reevaluate on changes in the resource dependency hierarchy. Depending on what you want done - you would approach it differently in your case. You can update the styles/templates to change the base colors, you can change visual states to make these respond to a state change that would change the colors, you can write an attached behavior (using an attached property directly or some open source WinRT behaviors implementation) that you would set on your data points that would update the brushes based on event or bound property, you can traverse the visual tree to update the colors based or you can create two almost identical, overlaid chart controls with different colors and change the colors by changing visibility of the chart controls. Then again maybe you could somehow just bind the brush of a pie chart data point to the underlying data - I haven't checked if that's possible, but if it isn't - you could modify the code of the chart controls to give you that feature (it's the power of open source!)