Windows phone create animation of controls - c#

I need to load some images and show on grid (with simple animation). I have
Image img = IconWithId(i);
// set some properties
//...
img.Tap += img_Tap;
img.ImageOpened += img_ImageOpened;
gameView.Children.Add(img);
In event img_ImageOpened i create animation
void img_ImageOpened(object sender, RoutedEventArgs e)
{
Image img = sender as Image;
Storyboard story = new Storyboard();
DoubleAnimation dAnimation = new DoubleAnimation();
dAnimation.From = 0;
dAnimation.To = 1;
dAnimation.Duration = new Duration(TimeSpan.FromMilliseconds(100));
Storyboard.SetTarget(dAnimation, img);
Storyboard.SetTargetProperty(dAnimation, new PropertyPath(OpacityProperty));
story.Children.Add(dAnimation);
story.Begin();
}
I think i have animation which should show image but it don't work. Image loaded without animation. What can i do?
PS i need to animation when images will close. I think to use event unloaded
Sorry for my english

I tested your code on a Windows Phone 8 with Phone 8 SDK
Your code works perfectly fine.
You need to change the duration to a longer period. 100ms way too fast. You won't be able to see it quick enough.
Change it to something longer like this
dAnimation.Duration = new Duration(TimeSpan.FromMilliseconds(5000));

Related

How do you detect if a RichTextBlock has overflow content in Windows Store apps?

I can't seem to ever get HasOverflowContent to fire on a RichTextBlock, even if I force it to update its layout. Here is what I've tried:
public MainPage()
{
this.InitializeComponent();
RichTextBlock block = new RichTextBlock();
RichTextBlockOverflow overflow = new RichTextBlockOverflow();
block.OverflowContentTarget = overflow;
block.Width = 100;
block.Height = 100;
Paragraph paragraph = new Paragraph();
for (int i = 0; i < 1000; i++)
{
Run run = new Run();
run.Text = "FILLER";
paragraph.Inlines.Add(run);
}
block.Blocks.Add(paragraph);
block.UpdateLayout();
if (block.HasOverflowContent)
{
// This line will never be hit.
}
MainGrid.Children.Add(block);
}
Why isn't HasOverflowContent signaling it that it does, in fact, have overflow content?
Edit: Okay, I was able to subscribe to this.Loaded on the MainPage constructor and this setting does show up correctly in such a case, however, its not good enough for my application so how can I check this outside of the loaded event?
So, it looks like it has to be added to the Visual Tree. It won't render it otherwise. Once added, I can call RenderTargetBitmap renderTargetBitmap = new RenderTargetBitmap(); and await renderTargetBitmap.RenderAsync(contentToBePrinted); I can make this work for printing from metro apps by adding the RichTextBlock in a Grid with 0 opacity, and all RichTextBlockOverflow's also to that grid on run-time, so that I can get them to render and also check the HasOverflowContent flag. Its the only way I could make it work the way I want it to.

Display loading while Caching image from URL

I have a code in WPF C# that i use to load images from the web as such:
if (myImgURL != "")
{
var imgBitmap = new BitmapImage();
imgBitmap.BeginInit();
imgBitmap.UriSource = new Uri(myImgURL, UriKind.RelativeOrAbsolute);
imgBitmap.CacheOption = BitmapCacheOption.OnLoad;
imgBitmap.EndInit();
myImgControl.Source = imgBitmap;
}
It works perfectly but sometimes it takes a while before the images get displayed (if internet is slow and all). How can I have a ProgressRing (from the Mahapps.Metro toolkit) display and be enabled while the image loads and then disappear when the image is displayed?
I am not aware of any event trigger for when an image is being downloaded and when it is fully loaded.
Take a look at the following events in class BitmapSource (the base class of BitmapImage):
DownloadProgress
DownloadCompleted
DownloadFailed
And just a note. You are creating a BitmapImage from an Uri and showing it immediately. Hence there is no need to set BitmapCacheOption.OnLoad (which afaik is necessary only if you load from a stream that should be closed immediately after EndInit). So you could shorten your code like this:
if (!string.IsNullOrEmpty(myImgURL))
{
var imgBitmap = new BitmapImage(new Uri(myImgURL));
myImgControl.Source = imgBitmap;
if (imgBitmap.IsDownloading)
{
// start download animation here
imgBitmap.DownloadCompleted += (o, e) =>
{
// stop download animation here
};
imgBitmap.DownloadFailed += (o, e) =>
{
// stop download animation here
};
}

WP7/8 changing InputScope dynamically after an event using C#

I'm making an app for Windows Phone, I've been trying for ages to get the InputScope of the main text box to change when the orientation is changed to landscape (so that the keyboard takes up less space in landscape without the autocorrect bar), and back again.
I experimented with a second text box and hiding the others upon an orientation change, but this did not work neatly. :P
Try as I might I can't get this to work and can find no way to change the InputScope value after the OrientationChangedEvent argument, which has worked nicely in changing the position of the elements of the page around orientations.
I'm still fairly new to developing apps with C# and XAML, and I hope there's a nice easy way to set the InputScope of my text box that one of you awesome people could show me!
-EDIT : Here's the event handler, everything inside there works absolutely fine, but any way I try to add anything to do with InputScope does not work :(
private void MainPage_OrientationChanged(object sender, OrientationChangedEventArgs e)
{
if ((e.Orientation & PageOrientation.Portrait) == (PageOrientation.Portrait))
{
//Portrait
PlaceholderText.FontSize = 29.333;
PlaceholderText.Padding = new Thickness (0,0,0,0);
MainTweet.FontSize = 29.333;
MainTweet.Padding = new Thickness (12,8,12,8);
Counter.Margin = new Thickness (0,212,28,0);
}
else
{
//Landscape
PlaceholderText.FontSize = 23;
PlaceholderText.Padding = new Thickness (8,0,0,0);
MainTweet.FontSize = 22;
MainTweet.Padding = new Thickness (16,8,180,0);
Counter.Margin = new Thickness (0,-18,28,0);
}
}
MainTweet.Text is the textbox that the keyboard is focusing on by default, when the page is changed to landscape I'd love to be able to change this from the "Search" InputScope to another, probably "URL". The stuff currently in there rearranges elements on the page nicely when the orientation is changed, I appreciate it might not look that neat...
There are multiple "orientation" states in the enumeration - not just Portrait and Landscape. The following worked for me to change the scope (on Windows Phone 7.5 emulator):
if (e.Orientation == PageOrientation.Landscape
|| e.Orientation == PageOrientation.LandscapeRight
|| e.Orientation == PageOrientation.LandscapeLeft)
{
InputScope inputScope = new InputScope();
InputScopeName inputScopeName = new InputScopeName();
inputScopeName.NameValue= InputScopeNameValue.Url;
inputScope.Names.Add(inputScopeName);
textBox1.InputScope = inputScope;
}
So you'd drop that into your MainPage_OrientationChanged event handler.

dynamically handling events for an image

I'm currently working on a program where there are multiple "icons" dynamically added to a window. Each one of these "icons" (which is actually a image with a label underneath it) represents a device in a network. When the user double clicks on an icon, it needs to open a window where the user can change the properties of that specific device.
I already have the window created, along with the code to dynamically add images to a window. My problem is that since each icon is dynamically added, they use the same event handler. since each icon uses the same handler, it seems impossible to have each icon open its respective device.
Here is a part of the code which is run when a user adds a new device along with the event handler it uses:
//create new device
devices.Add(new Device(ipaddress, hn, un, pw, cm, lx, ly, tp, pl, nt, dn));
images.Add(new Image());
//create image for main window
images[images.Count - 1].Width = 50;
images[images.Count - 1].Height = 35;
images[images.Count - 1].Stretch = Stretch.Fill;
BitmapImage logo = new BitmapImage();
logo.BeginInit();
logo.UriSource = new Uri(deviceImages[tp], UriKind.Relative);
logo.CacheOption = BitmapCacheOption.OnLoad;
logo.EndInit();
images[images.Count - 1].Source = logo;
images[images.Count - 1].Cursor = Cursors.Hand;
images[images.Count - 1].Margin = new System.Windows.Thickness(lx-25, ly-25, 0, 0);
images[images.Count - 1].VerticalAlignment = System.Windows.VerticalAlignment.Top;
images[images.Count - 1].HorizontalAlignment = System.Windows.HorizontalAlignment.Left;
images[images.Count - 1].MouseDown += new MouseButtonEventHandler(deviceIcon_MouseDown);
ConnexMainWindow.grid1.Children.Add(images[images.Count - 1]);
public void deviceIcon_MouseDown(object sender, MouseButtonEventArgs e)
{
ConnexDeviceWindow deviceWindow = new ConnexDeviceWindow();
deviceWindow.Show();
}
As you can see, I'm not currently passing the device window the device since there isn't really any way to do so from the event handler.
My question is: Is there a way to dynamically create an event handler, for each image i add, so that i can pass the function the proper device that each image represents?
One common strategy to identify the control which fired the event is to use the Tag property of the control to store some information.
I don't know what your device model looks like, but let's assume the ip-address is unique among all the devices. You can attach that to the Image control:
images[images.Count - 1].Tag = ipaddress
In your event handler you can grab that tag to find the device (assuming the devices collection is available on class-level):
public void deviceIcon_MouseDown(object sender, MouseButtonEventArgs e)
{
Image image = e.Source as Image;
if (image != null)
{
string ipAddress = (string)image.Tag;
Device device = devices.FirstOrDefault(d => d.IpAddress == ipAddress);
if (device != null)
{
ConnexDeviceWindow deviceWindow = new ConnexDeviceWindow(device);
deviceWindow.Show();
}
}
}

Change button background

After several attempts to change the background of a button, and getting errors of casting and things like that I finnaly got to this point:
Uri dir = new Uri("red_flag.png",UriKind.RelativeOrAbsolute);
ImageSource source = new System.Windows.Media.Imaging.BitmapImage(dir);
ImageBrush bru = new ImageBrush();
bru.ImageSource=source;
bru.Opacity = 100;
This code does not generate errors, but I can't see the changes when I call:
button1.background = bru;
It just makes anything! :(
found the answer myelf after reading Mick's answer, I share with you what I did:
Uri dir = new Uri("red_flag.png", UriKind.Relative);
ImageSource source = new System.Windows.Media.Imaging.BitmapImage(dir);
Image image = new Image();
image.Source = source;
StackPanel stack = new StackPanel();
stack.Children.Add(image);
myButton.Content = stack;
Thanks for your help
Update 1:
For best results set the padding property of your button to 0 (in each of the cases) so the image can resize automatically to fill all the button, please note this could hide your actual content, in my case this was what I wanted.
If this code is part of the click event handler for the same button you will have this problem.
Peter Torr explains why here and offers a solution.
Why can't I change the Background of my Button on a Click event?

Categories