Wer, wie ich, seine Termine rund um die WM 2010 planen muss, der tut sich bei den vielen Spielen manchmal recht schwer, den Überblick zu bewahren.
Meine Kollegen aus der Office-Truppe haben dafür die Lösung: Excel und Outlook-Termine zum kostenfreien Download.
Mehr Infos gibt es hier.
In den USA ist der Begriff “netflixen” so gängig wie bei uns das Wort “googlen”. Es bedeutet soviel wie das Ausleihen von Videos.
Netflix ist seit Jahren regelmäßiger Gast auf der MIX und stellt dort ihre aktuellen Lösungen vor, die inzwischen vollständig auf .NET, Silverlight und jetzt auch Windows Phone 7 basieren.
Meine Kollegin Laura Foy stellt in diesem Video auf Channel 9, die aktuelle Lösung von Netflix vor, so wie sie auf der Mix gezeigt wurde. Sehr beeindruckend, und meiner Meinung nach der absolut erste gute Video-Ausleih-Client für mobile Geräte.
Mehr Informationen
Vor der zweiten Keynote auf der MIX10 stand ein Kollege auf der Bühne und hat Project Gustav live auf der Bühne verwendet um sehr realistische Zeichnungen zu erstellen.
Typische Zeichenprogramme haben den Nachteil, das sie keinen echten Pinsel und dessen natürlichen Eigenschaften nachahmen können. Das Project Gustav von Microsoft Research ist ein Prototyp für realistisches Zeichnen am Computer. Es kann mit mehreren Eingaben gleichzeitig umgehen (Multitouch mit mehr als vier gleichzeitigen Berührungen des Bildschirms). Darüber hinaus werden modernste Modelling- und Pinselsimulations-Algorithmen angewendet, die selbst das Überzeichnen von Farbe realistisch darstellen können und anschließend auch noch ein Verwischen erlauben.
Vor zwei Jahren wurde das WorldWide Telescope Projekt von Microsoft Research vorgestellt. Vor wenigen Tagen, wurde diese nun in Bing Maps integriert. Damit hat man nun die Möglichkeit von jedem beliebigen Ort der Welt von der Street Side View (die noch nicht überall erhältlich ist), in das Weltall zu blicken und das Sternensystem zu erkunden.
Es ist sogar möglich dies zu verschiedenen Tagen und Uhrzeiten zu tun, damit lassen sich z.B. der Sternenhimmel an seinem Geburtstag simulieren.
Video
Link: www.bing.com/maps/explore –> Map Apps
Eines der Kernthemen der diesjährigen MIX war der Internet Explorer 9 und die Mitarbeit am HTML5-Standard. Dazu sind jetzt die Videos verfügbar.
Viel Spaß, TheOliver
A great feature in Silverlight 3 is the capability to install applications out-of-browser. For those applications it is very useful to check, whether there is an update at the original location, where they are coming from.
My simple application checks this using behaviors, which can be reused for any applications. Just one feature is very important to enable –> The Out-Of-Browser Feature in your application.
The install-Behavior checks the Install-State of the application, and hide the control which contains the Install-Feature, if it is already installed.
Live Preview
The in-browser version, with an Install button.
The same application after installing it local.
The out-of-browser-application without the install button (because, it is already installed )
The Update Dialog, when an update is available. You will not see this feature in the preview, because I will not update it regularly.
No code needed in your application
XAML-Code
<UserControl x:Class="SmallTextEditor.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="400" xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" xmlns:TheOliver="clr-namespace:TheOliver.Controls"> <Grid x:Name="LayoutRoot" Background="White"> <i:Interaction.Triggers> <i:EventTrigger EventName="Loaded"> <TheOliver:CheckForUpdateBehavior /> </i:EventTrigger> </i:Interaction.Triggers> <Grid.RowDefinitions> <RowDefinition Height="28*" /> <RowDefinition Height="272*" /> </Grid.RowDefinitions> <RichTextBox x:Name="_textbox" Grid.Row="1" IsEnabled="False" /> <StackPanel HorizontalAlignment="Left" Name="stackPanel1" Orientation="Horizontal"> <Button Content="New" Height="23" Name="_new" IsEnabled="False" /> <Button Content="Open" Height="23" Name="_open" IsEnabled="False" /> <Button Content="Save" Height="23" Name="_save" IsEnabled="False" /> <Button Content="Install Local" Height="23" Name="_install"> <i:Interaction.Triggers> <i:EventTrigger EventName="Click"> <TheOliver:InstallOutOfBrowserBehavior /> </i:EventTrigger> </i:Interaction.Triggers> </Button> </StackPanel> </Grid> </UserControl>
Sourcecode for Install-Out-Of-Browser-Behavior
// Copyright © Microsoft Corporation. All Rights Reserved. // This code released under the terms of the // Microsoft Public License (MS-PL, http://opensource.org/licenses/ms-pl.html.) using System.Windows; using System.Windows.Interactivity; using System.Windows.Controls; namespace TheOliver.Controls { public class InstallOutOfBrowserBehavior : TargetedTriggerAction<FrameworkElement> { UIElement _element; protected override void OnAttached() { _element = this.Target as UIElement; if (!Application.Current.IsRunningOutOfBrowser) { Application.Current.InstallStateChanged += (s, e) => { CheckInstallState(); }; CheckInstallState(); if (_element is Button) { (_element as Button).Click += (s, e) => { InstallOOB(); }; } else { _element.MouseLeftButtonDown += (s, e) => { InstallOOB(); }; } } else { _element.Visibility = Visibility.Collapsed; } base.OnAttached(); } private void InstallOOB() { if (Application.Current.InstallState != InstallState.Installed && Application.Current.InstallState != InstallState.Installing) { Application.Current.Install(); } } private void CheckInstallState() { if (Application.Current.InstallState == InstallState.Installed || Application.Current.InstallState == InstallState.Installing) { _element.Visibility = Visibility.Collapsed; } else { _element.Visibility = Visibility.Visible; } } protected override void Invoke(object o) { } } }
Sourcecode for CheckForUpdateBehavior
// Copyright © Microsoft Corporation. All Rights Reserved. // This code released under the terms of the // Microsoft Public License (MS-PL, http://opensource.org/licenses/ms-pl.html.) using System.Windows; using System.Windows.Interactivity; namespace TheOliver.Controls { public class CheckForUpdateBehavior : TargetedTriggerAction<FrameworkElement> { UIElement _element; protected override void OnAttached() { // Works only out-of-browser if (Application.Current.IsRunningOutOfBrowser) { _element = this.AssociatedObject as UIElement; } base.OnAttached(); } protected override void Invoke(object o) { if (_element != null) { Application.Current.CheckAndDownloadUpdateCompleted += (s, e) => { if (e.UpdateAvailable) { MessageBox.Show(UpdateIsAvailableMessageText); } }; Application.Current.CheckAndDownloadUpdateAsync(); } } public string UpdateIsAvailableMessageText { get { return (string)GetValue(UpdateIsAvailableMessageTextProperty); } set { SetValue(UpdateIsAvailableMessageTextProperty, value); } } public static readonly DependencyProperty UpdateIsAvailableMessageTextProperty = DependencyProperty.Register( "UpdateIsAvailableMessageText", typeof(string), typeof(CheckForUpdateBehavior), new PropertyMetadata("Update is available. Please restart your application")); } }
Solutiondownload
Best regards, The-Oliver
Last week I did it again, five nice demos for Silverlight 3 usage, with live Previews and Sourcecode.
22.03.2010 – Silverlight 3 Deep Zoom Mouse Zoom Features Behavior // Preview
23.03.2010 – Silverlight 3 Deep Zoom Navigate Home Behavior // Preview
24.03.2010 – Silverlight 3 Deep Zoom Randomizing Images // Preview
25.03.2010 – Silverlight 3 Deep Zoom Slide Show Behavior // Preview
26.03.2010 – Silverlight 3 Mouse 3D Behavior // Preview
If you have any suggestions for nice Daily Demos, please comment ..
Recent demos:
15.03.2010 – Silverlight 3: Text Tipping Control // [Preview]
16.03.2010 – Silverlight 3: Image Spindle // [Preview]
17.03.2010 – Silverlight 3: Image Stack // [Preview]
18.03.2010 – Silverlight 3: Behavior – 3D Hover Effect // [Preview]
19.03.2010 – Silverlight 3: Trigger Action – Fullscreen // [Preview]
In der MSDN Library stehen sechs neue Artikel zur Verfügung, die demonstrieren, wie man mit Visual Studio 2010 Windows-Programme mit einer grafischen Benutzeroberfläche in Visual C++ erstellen kann. Alle Artikel von Richard und Alexander Kaiser basieren auf dem Fachbuch "C++ mit Microsoft Visual C++ 2008". Folgende Themen sind verfügbar:
· Erste Schritte: Einfache Windows .NET Programme mit Visual C++: Dieser Artikel zeigt an sehr einfachen Beispielen, wie man mit Visual Studio 2010 und C++ Windows-Programme mit einer grafischen Benutzeroberfläche entwickeln kann.
· Steuerelemente für die Benutzeroberfläche: Ein Überblick über einige der wichtigsten Steuerelemente von Windows-Programmen. Dabei werden am Beispiel eines Labels, einer TextBox und eines Buttons einige der wichtigsten Eigenschaften, Methoden und Ereignisse vorgestellt. Im Vordergrund steht, wie man diese unter C++ anspricht.
· Windows Forms-Anwendungen mit Standard-C++: Beschreibt ein allgemein einsetzbares Programmschema, mit dem Windows Forms-Anwendungen mit Anweisungen in Standard-C++ geschrieben werden können.
· C++/CLI-Erweiterungen: Visual C++ verwendet in Windows Forms-Anwendungen eine Erweiterung von Standard-C++, die als C++/CLI bezeichnet wird. Die C++/CLI-Erweiterungen integrieren einige C#-Konzepte in C++ und ermöglichen die Nutzung der.NET-Bibliothek auch unter C++.
· .NET-Klassen in C++ Windows Forms-Anwendungen: In einer C++ Windows Forms-Anwendung steht im Wesentlichen die gesamte .NET-Bibliothek zur Verfügung. An einigen einfachen Beispielen wird gezeigt, wie .NET-Klassen in C++ verwendet werden können.
· Win32-DLLs und Win32-API-Funktionen in Windows Forms-Anwendungen verwenden: In einer C++ Windows Forms-Anwendung können auch Win32-DLLs verwendet werden. Das wird am Beispiel von Win32-API-Funktionen gezeigt.
Die verwendeten Beispiele stehen als Visual Studio-Projekt zum Download zur Verfügung. Alle Artikel und Beispiele sind auch für Visual Studio 2005 und Visual Studio 2008 in der MSDN Library zu finden.
Gerade wurde eine neue Aktualisierung der Twitter Maps Application in der Bing Maps Application Gallerie eingestellt. Jetzt hat man die Möglichkeit diese App auch in seine eigene Webseite einzubinden.
Das Ganze geschieht in nur vier Schritten:
Link: http://www.bing.com/maps/explore –> Map Apps –> Twitter
Auf Codeplex ist jetzt eine sehr coole Synthesizer-Bibliothek für Silverlight veröffentlich worden.
Mit der können sich die Depeche Mode und Silverlight-Fans mal so richtig austoben und den nächsten Super-Synthie-Hit coden.
Eine Demo gibt es hier.
Die Codeplex-Bibliothek ist hier zu finden.
A very cool new feature in Silverlight 3 is the support of perspective 3D. And now image what you can do with 3D, your Mouse and Behaviors. Apply 3D capabilities to every control you like.
Ta da … the Silverlight Mouse 3D Behavior
Livepreview
<UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" xmlns:TheOliver_Controls="clr-namespace:TheOliver.Controls" x:Class="Mouse3DBehavior.MainPage" d:DesignHeight="300" d:DesignWidth="400"> <Grid x:Name="LayoutRoot" Background="White"> <Image Source="20080815_114932.jpg" Stretch="Fill"> <i:Interaction.Behaviors> <TheOliver_Controls:Mouse3DBehavior /> </i:Interaction.Behaviors> </Image> </Grid> </UserControl>
Sourcecode
// Copyright © Microsoft Corporation. All Rights Reserved. // This code released under the terms of the // Microsoft Public License (MS-PL, http://opensource.org/licenses/ms-pl.html.) using System.Windows; using System.Windows.Input; using System.Windows.Interactivity; using System.Windows.Media; namespace TheOliver.Controls { public class Mouse3DBehavior : Behavior<UIElement> { PlaneProjection _planeProjection; bool _buttonPressed = false; Point _originPoint; UIElement _target; FrameworkElement _control; UIElement _targetParent; double _controlHeight; double _controlWidth; protected override void OnAttached() { base.OnAttached(); _target = this.AssociatedObject; _control = _target as FrameworkElement; _control.LayoutUpdated += (s, e) => { _targetParent = _control.Parent as UIElement; _planeProjection = new PlaneProjection(); _target.Projection = _planeProjection; _targetParent.MouseLeftButtonDown += new MouseButtonEventHandler(AssociatedObject_MouseLeftButtonDown); _targetParent.MouseLeftButtonUp += new MouseButtonEventHandler(AssociatedObject_MouseLeftButtonUp); _targetParent.MouseMove += new MouseEventHandler(AssociatedObject_MouseMove); _targetParent.MouseLeave += new MouseEventHandler(AssociatedObject_MouseLeave); _controlHeight = (_targetParent as FrameworkElement).ActualHeight; _controlWidth = (_targetParent as FrameworkElement).ActualWidth; }; } void AssociatedObject_MouseLeave(object sender, MouseEventArgs e) { _buttonPressed = false; } void AssociatedObject_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { _target.CaptureMouse(); _originPoint = GetPoint(e); _buttonPressed = true; } void AssociatedObject_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) { _buttonPressed = false; _target.ReleaseMouseCapture(); } void AssociatedObject_MouseMove(object sender, MouseEventArgs e) { if (_buttonPressed) { PlaneProjection pp = _target.Projection as PlaneProjection; Point pt = GetPoint(e); double widthPixPerAngle = _controlWidth / 720; double heightPixPerAngle = _controlHeight / 720; double diffY = (pt.X - _controlWidth / 2) * widthPixPerAngle; double diffX = (pt.Y - _controlHeight / 2) * heightPixPerAngle; _originPoint = pt; if (YEnable) { pp.RotationY = diffY; } if (XEnable) { pp.RotationX = diffX; } } } private Point GetPoint(MouseEventArgs e) { Point point = e.GetPosition(_targetParent); return point; } protected override void OnDetaching() { base.OnDetaching(); this.AssociatedObject.Projection = null; _targetParent.MouseLeftButtonDown -= new MouseButtonEventHandler(AssociatedObject_MouseLeftButtonDown); _targetParent.MouseLeftButtonUp -= new MouseButtonEventHandler(AssociatedObject_MouseLeftButtonUp); _targetParent.MouseMove -= new MouseEventHandler(AssociatedObject_MouseMove); _targetParent.MouseLeave -= new MouseEventHandler(AssociatedObject_MouseLeave); } public double MoveFactor { get { return (double)GetValue(MoveFactorProperty); } set { SetValue(MoveFactorProperty, value); } } public static readonly DependencyProperty MoveFactorProperty = DependencyProperty.Register( "MoveFactor", typeof(double), typeof(Mouse3DBehavior), new PropertyMetadata(1.0)); public bool XEnable { get { return (bool)GetValue(XEnableProperty); } set { SetValue(XEnableProperty, value); } } public static readonly DependencyProperty XEnableProperty = DependencyProperty.Register( "XEnable", typeof(bool), typeof(Mouse3DBehavior), new PropertyMetadata(true)); public bool YEnable { get { return (bool)GetValue(YEnableProperty); } set { SetValue(YEnableProperty, value); } } public static readonly DependencyProperty YEnableProperty = DependencyProperty.Register( "YEnable", typeof(bool), typeof(Mouse3DBehavior), new PropertyMetadata(true)); } }
Das eigene App auf dem neuen Windows Phone 7 Series? Für Studenten kann aus diesem Traum beim Windows Phone 7 Series Coding Camp auf der Burg Freusburg Wirklichkeit werden!
Unter dem Motto „Entdecke die neue Welt des Mobile Developments!“ zeigt Microsoft Studenten vom 7.-9. Mai auf der alten Ritterburg in einem unvergleichlichen Ambiente, was diese neue Welt alles zu bieten hat. Gemeinsam mit den Microsoft Experten Frank Prengel, auch bekannt als Dr. Mobile, Oliver Scheer alias Mr. deep zoom und Tom Wendel alias the ant man erwartet die Studenten die ultimative Coding-Erfahrung! Ziel ist es zudem, die fertigen Apps zusätzlich beim Windows Phone 7 "Rockstar" Award“ des Imagine Cups einzureichen. So haben die Studenten zusätzlich die Chance auf eine Reise zum internationalen Finale in Warschau und auf Preise im Wert von $8.000!
Wer kann dabei sein?
Studenten, die sich für Mobile Development interessieren und für die XNA und Silverlight keine Fremdwörter sind, können sich auf einen der begehrten Plätze bewerben:
Hierzu müssen sie eine Begründung, warum gerade sie einen der 30 Plätze im Coding Camp bekommen sollten, an youdream@microsoft.com schicken:
z.B. Schildere uns kurz und knapp Deine Erfahrungen mit Mobile Entwicklung. Was reizt Dich an Mobile Development? Welche Apps wolltest Du schon immer mal bauen?
Studenten, die einen der begehrten Plätze ergattern, müssen lediglich die Anreise selbst übernehmen, Übernachtung, Verpflegung etc. übernimmt Microsoft!
Deep Zooms are very useful for catalog systems or holiday photos. You can get a big impression of all your images, but when you want to step through each single picture, navigation could get a little bit challenging … until now. Here is a small behavior to step through each single photo in a deep zoom collection.
XAML Code
<UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" xmlns:TheOliver_Controls="clr-namespace:TheOliver.Controls" x:Class="DeepZoomMouseBehavior.MainPage" d:DesignHeight="300" d:DesignWidth="400"> <Grid x:Name="LayoutRoot" Background="White"> <TextBlock Text="Deep Zoom Sample" /> <MultiScaleImage x:Name="_msi" Source="Images/dzc_output.xml" Margin="0,19,0,0"> <i:Interaction.Behaviors> <TheOliver_Controls:DeepZoomBehavior /> </i:Interaction.Behaviors> </MultiScaleImage> <Button x:Name="_home" HorizontalAlignment="Right" VerticalAlignment="Top" Width="53" Content="Home"> <i:Interaction.Triggers> <i:EventTrigger EventName="Click"> <TheOliver_Controls:DeepZoomNavigateHomeBehavior TargetName="_msi" /> </i:EventTrigger> </i:Interaction.Triggers> </Button> <Button x:Name="_shuffle" HorizontalAlignment="Right" VerticalAlignment="Top" Width="53" Content="Shuffle" Margin="0,0,57,0"> <i:Interaction.Triggers> <i:EventTrigger EventName="Click"> <TheOliver_Controls:DeepZoomRandomImageArrangeBehavior TargetName="_msi" XOffset="1" YOffset="1" /> </i:EventTrigger> </i:Interaction.Triggers> </Button> <Button x:Name="_slideShow" HorizontalAlignment="Right" VerticalAlignment="Top" Width="68" Content="Slideshow" Margin="0,0,114,0"> <i:Interaction.Triggers> <i:EventTrigger EventName="Click"> <TheOliver_Controls:DeepZoomSlideShowBehavior TargetName="_msi" /> </i:EventTrigger> </i:Interaction.Triggers> </Button> </Grid> </UserControl>
// Copyright © Microsoft Corporation. All Rights Reserved. // This code released under the terms of the // Microsoft Public License (MS-PL, http://opensource.org/licenses/ms-pl.html.) using System.Windows; using System.Windows.Controls; using System.Windows.Interactivity; namespace TheOliver.Controls { public class DeepZoomSlideShowBehavior : TargetedTriggerAction<MultiScaleImage> { private MultiScaleImage _msi; private int _count = 0; private int _totalImages; protected override void Invoke(object o) { if (this._msi == null) { this._msi = this.Target; _totalImages = _msi.SubImages.Count; } if (_count < _totalImages) { ZoomOnImage(_count); } else { _count = 0; ZoomOnImage(_count); } } private void ZoomOnImage(int subImageIndex) { _count++; MultiScaleSubImage subImage = _msi.SubImages[subImageIndex]; double scaleBy = 1 / subImage.ViewportWidth; Rect subImageRect = new Rect(-subImage.ViewportOrigin.X * scaleBy, -subImage.ViewportOrigin.Y * scaleBy, scaleBy, (1 / subImage.AspectRatio) * scaleBy); if ((this._msi.Width / this._msi.Height) > subImage.AspectRatio) { double targetViewportWidth = subImageRect.Height * this._msi.AspectRatio; double targetPointX = (targetViewportWidth - subImageRect.Width) / 2; this._msi.ViewportOrigin = new Point(subImageRect.X - targetPointX, subImageRect.Y); this._msi.ViewportWidth = targetViewportWidth; } else { this._msi.ViewportWidth = subImageRect.Width; this._msi.ViewportOrigin = new Point(subImageRect.X, subImageRect.Y); } } } }
Alle wichtigen Informationen über die neue Version von Microsoft Visual Studio … 2010 findet man auf der neu gestalteten Webseite im neuen Look&Feel auf www.microsoft.de/visualstudio
Vorgestern waren wir in der Redaktion der PCWelt in München und haben dort Interviews zu Internet Explorer 9 Platform Preview und Windows Phone 7 Series gegeben.
Das Interview ist bereits live hier zu betrachten.
Deep Zooms in Silverlight are great. On key feature is, that you have access to every sub image. So … why don’t we use this with animations?
<UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" xmlns:TheOliver_Controls="clr-namespace:TheOliver.Controls" x:Class="DeepZoomMouseBehavior.MainPage" d:DesignHeight="300" d:DesignWidth="400"> <Grid x:Name="LayoutRoot" Background="White"> <TextBlock Text="Deep Zoom Sample" /> <MultiScaleImage x:Name="_msi" Source="Images/dzc_output.xml" Margin="0,19,0,0"> <i:Interaction.Behaviors> <TheOliver_Controls:DeepZoomBehavior /> </i:Interaction.Behaviors> </MultiScaleImage> <Button x:Name="_home" HorizontalAlignment="Right" VerticalAlignment="Top" Width="53" Content="Home"> <i:Interaction.Triggers> <i:EventTrigger EventName="Click"> <TheOliver_Controls:DeepZoomNavigateHomeBehavior TargetName="_msi" /> </i:EventTrigger> </i:Interaction.Triggers> </Button> <Button x:Name="_shuffle" HorizontalAlignment="Right" VerticalAlignment="Top" Width="53" Content="Shuffle" Margin="0,0,57,0"> <i:Interaction.Triggers> <i:EventTrigger EventName="Click"> <TheOliver_Controls:DeepZoomRandomImageArrangeBehavior TargetName="_msi" XOffset="1" YOffset="1" /> </i:EventTrigger> </i:Interaction.Triggers> </Button> </Grid> </UserControl>
// Copyright © Microsoft Corporation. All Rights Reserved. // This code released under the terms of the // Microsoft Public License (MS-PL, http://opensource.org/licenses/ms-pl.html.) using System; using System.Collections.Generic; using System.Windows; using System.Windows.Controls; using System.Windows.Interactivity; using System.Windows.Media.Animation; namespace TheOliver.Controls { public class DeepZoomRandomImageArrangeBehavior : TargetedTriggerAction<MultiScaleImage> { private List<MultiScaleSubImage> _randomList = new List<MultiScaleSubImage>(); int _totalColumns = 0; int _totalRows = 0; private MultiScaleImage _msi; public double XOffset { get { return (double)GetValue(XOffsetProperty); } set { SetValue(XOffsetProperty, value); } } public static readonly DependencyProperty XOffsetProperty = DependencyProperty.Register( "XOffset", typeof(double), typeof(DeepZoomRandomImageArrangeBehavior), new PropertyMetadata(1.25, XOffsetChanged)); private static void XOffsetChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { } public double YOffset { get { return (double)GetValue(YOffsetProperty); } set { SetValue(YOffsetProperty, value); } } public static readonly DependencyProperty YOffsetProperty = DependencyProperty.Register( "YOffset", typeof(double), typeof(DeepZoomRandomImageArrangeBehavior), new PropertyMetadata(1.25, YOffsetChanged)); private static void YOffsetChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { } public int Speed { get { return (int)GetValue(SpeedProperty); } set { SetValue(SpeedProperty, value); } } public static readonly DependencyProperty SpeedProperty = DependencyProperty.Register( "Speed", typeof(int), typeof(DeepZoomRandomImageArrangeBehavior), new PropertyMetadata(1000, SpeedChanged)); private static void SpeedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { } protected override void Invoke(object o) { _msi = this.Target; ArrangeIntoGrid(); } private void ArrangeIntoGrid() { _randomList = RandomizedListOfImages(); int totalImagesAdded = 0; double totalWidth = 0; double xoffset = XOffset; double yoffset = YOffset; double margin = .1; if (_randomList.Count > 1) { int numberOfImages = _randomList.Count; _totalColumns = 0; _totalColumns = (int)Math.Ceiling(Math.Sqrt(numberOfImages)); _totalRows = numberOfImages / (_totalColumns - 1); totalWidth = _totalColumns * xoffset; Storyboard moveStoryboard = new Storyboard(); for (int row = 0; row < _totalRows; row++) { for (int col = 0; col < _totalColumns; col++) { if (numberOfImages != totalImagesAdded) { MultiScaleSubImage currentImage = _randomList[totalImagesAdded]; currentImage.ViewportWidth = 1; Point currentPosition = new Point(0, 0); Point futurePosition = new Point(-xoffset * col, -yoffset * row); // Create Animation PointAnimationUsingKeyFrames moveAnimation = new PointAnimationUsingKeyFrames(); // Create Keyframe SplinePointKeyFrame startKeyframe = new SplinePointKeyFrame(); startKeyframe.Value = currentPosition; startKeyframe.KeyTime = KeyTime.FromTimeSpan(TimeSpan.Zero); startKeyframe = new SplinePointKeyFrame(); startKeyframe.Value = futurePosition; startKeyframe.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(Speed)); KeySpline ks = new KeySpline(); ks.ControlPoint1 = new Point(0, 1); ks.ControlPoint2 = new Point(1, 1); startKeyframe.KeySpline = ks; moveAnimation.KeyFrames.Add(startKeyframe); Storyboard.SetTarget(moveAnimation, currentImage); Storyboard.SetTargetProperty(moveAnimation, new PropertyPath("ViewportOrigin")); moveStoryboard.Children.Add(moveAnimation); totalImagesAdded++; } else { break; } } } if (!_msi.Resources.Contains("myAnim")) { _msi.Resources.Add("myAnim", moveStoryboard); } this._msi.ViewportOrigin = new Point(-margin, -margin); this._msi.ViewportWidth = totalWidth + margin; // Play Storyboard moveStoryboard.Begin(); } else { MultiScaleSubImage currentImage = _randomList[0]; currentImage.ViewportWidth = 1 + 2 * margin; currentImage.ViewportOrigin = new Point(0, 0); this._msi.ViewportOrigin = new Point(-margin, -margin); this._msi.ViewportWidth = 1; } } private List<MultiScaleSubImage> RandomizedListOfImages() { List<MultiScaleSubImage> imageList = new List<MultiScaleSubImage>(); Random ranNum = new Random(); // Store List of Images foreach (MultiScaleSubImage subImage in _msi.SubImages) { subImage.Opacity = 1; imageList.Add(subImage); } int numImages = imageList.Count; // Randomize Image List for (int a = 0; a < numImages; a++) { MultiScaleSubImage tempImage = imageList[a]; imageList.RemoveAt(a); int ranNumSelect = ranNum.Next(imageList.Count); imageList.Insert(ranNumSelect, tempImage); } return imageList; } } }
Die xtopia[kompakt] Roadshow geht in die nächste Runde und Sie können dabei sein! Erleben Sie einen spannenden Abend mit interessanten Vorträgen zu Webdesign, RIA, Silverlight, User Experience und vieles, vieles mehr – und das Ganze kostenlos!
In insgesamt sechs Städten in Deutschland haben Sie die Möglichkeit an einer der Abendveranstaltungen teilzunehmen. Beginn ist jeweils 17 Uhr, Ende gegen 22.30 Uhr. Neben den Sessions wird es Gelegenheit geben, bei Getränken und Snacks sich untereinander auszutauschen und zu “networken”.
Es erwartet Sie ein bunter Mix an Themen. In verschiedenen Sessions werden Microsoft-Sprecher über alle Innovationen aus dem Bereich Web, Design, Usability und RIA sprechen. Darüberhinaus werden Kreativagenturen, wie Ergosin, UID, Designaffairs, UCD Plus und Neon Red vom Praxis-Einsatz neuester Technologien berichten. Das Usability Team der Nero AG wird des weiteren über den Einsatz von Microsoft Expression Studio im Entwicklungsprozess der neuen Version ihrer Brennsuite sprechen.
Jan Schenk (Microsoft): Heiter trotz wolkig - Cloud Computing mit Windows Azure
Cloud Computing ist in aller Munde. Das Konzept und die Philosophie hinter Windows Azure sehen Sie hier im Schnelldurchlauf: Für welche Einsatzbereiche macht Cloud Computing wirklich Sinn? Wann rechnet sich Windows Azure? Gehen Sie in dieser Session auf Tuchfühlung mit der Wolke!
Frank Prengel (Microsoft): Windows Phone – neue Ansätze, neue Möglichkeiten
Kurzinhalt: Das Jahr 2010 wird viele signifikante Neuerungen für Windows Phones bringen – für Anwender, Entwickler und Designer. Diese Session vermittelt Ihnen in komprimierter Form, wie Microsoft seine mobile Plattform auffrischt und Maßstäbe im Smartphone-Bereich setzen wird.
Oliver Scheer (Microsoft): Silverlight 4 – Die Highlights
Rich Internet Applications mit Microsoft Silverlight: Einfach, Schnell und Beeindruckend. Silverlight 4 bringt eine Fülle von neuen Möglichkeiten mit und macht das Entwickeln und Designen von interaktiven Webanwendungen noch einfacher. Dieser Vortrag zeigt die Highlights der neuen Version von Silverlight.
Tom Wendel (Microsoft): SharePoint 2010 spricht Silverlight
Mit der Einführung von SharePoint 2010 wächst zusammen, was zusammen gehört. Mit Hilfe von Silverlight lassen sich Daten in SharePoint perfekt visualisieren. Eine nahtlose Integration der beiden Technologien verschafft völlig neue Möglichkeiten – sei es direkt als Webpart oder als eigenständige Silverlight-Anwendung.
Clemens Lutsch & verschiedene Kreativagenturen: Silverlight & WPF in der Design-Praxis
Führende Design-Agenturen berichten von Erfahrungen mit WPF & Silverlight in aktuellen, innovativen Projekten. So erfahren Sie aus erster Hand, wie moderne UX mit modernen Tools entsteht.
Georg Christoph, Nero AG: Microsoft Expression im Einsatz bei Nero
Wie Expression dabei hilft, Brücken zwischen Usability, Design und Entwicklung zu bauen.
Jetzt heißt es schnell sein: Suchen Sie sich Ihre Lieblingsstadt aus und reservieren Sie sich sofort einen der begehrten Plätze.
Montag, 19.04.2010
München
Hilton München Park, Am Tucherpark 7, 80538 München
Zur Anmeldung
Dienstag, 20.04.2010
Karlsruhe
Best Western Karlsruhe, Ettlingerstr. 23, 76137 Karlsruhe
Mittwoch, 21.04.2010
Frankfurt / Bad Homburg
Maritim Bad Homburg, Ludwigstraße 3, 61348 Bad Homburg
Montag, 26.04.2010
Köln
Leonardo Hotel Köln, Waldecker Straße 11-15, 51065 Köln
Dienstag, 27.04.2010
Hamburg
Baseler Hof Hamburg, Esplanade 11, 20354 Hamburg
Mittwoch, 28.04.2010
Berlin
Mövenpick Berlin, Schöneberger Straße 3, 10963 Berlin
Weitere Informationen zu den einzelnen Sessions, detaillierte Agendas, News zu den Sprechern und vieles mehr finden Sie exklusiv hier im Silverlight & Expression Team Blog. Also am Besten direkt den Feed abonnieren und immer auf dem Laufenden bleiben.
Schöne Grüße
TheOliver
A common used feature in Deep Zoom Images is the “Home” Feature. If you zoom deep into an image you might get lost ;-). But don’t be afraid. The following behavior applied to you MultiScaleImage bring you back to the origin position (Home) of your image.
<UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" xmlns:TheOliver_Controls="clr-namespace:TheOliver.Controls" x:Class="DeepZoomMouseBehavior.MainPage" d:DesignHeight="300" d:DesignWidth="400"> <Grid x:Name="LayoutRoot" Background="White"> <TextBlock Text="Deep Zoom Sample" /> <MultiScaleImage x:Name="_msi" Source="Images/dzc_output.xml" Margin="0,19,0,0"> <i:Interaction.Behaviors> <TheOliver_Controls:DeepZoomBehavior /> </i:Interaction.Behaviors> </MultiScaleImage> <Button HorizontalAlignment="Right" VerticalAlignment="Top" Width="53" Content="Home"> <i:Interaction.Triggers> <i:EventTrigger EventName="Click"> <TheOliver_Controls:DeepZoomNavigateHomeBehavior TargetName="_msi" /> </i:EventTrigger> </i:Interaction.Triggers> </Button> </Grid> </UserControl>
Sourcecode for Behavior
// Copyright © Microsoft Corporation. All Rights Reserved. // This code released under the terms of the // Microsoft Public License (MS-PL, http://opensource.org/licenses/ms-pl.html.) using System.Windows.Interactivity; using System.Windows; using System.Windows.Controls; namespace TheOliver.Controls { public class DeepZoomNavigateHomeBehavior : TargetedTriggerAction<MultiScaleImage> { MultiScaleImage msi; protected override void Invoke(object parameter) { msi = this.Target as MultiScaleImage; msi.ViewportWidth = 1; msi.ViewportOrigin = new Point(0, 0); } } }
Deep Zoom is brilliant, awesome, super exciting … I LOVE DEEP ZOOM. And I love to create my own applications based on Deep Zoom. In Silverlight you can use Deep Zoom with the MultiScaleImage-Control. The challenge is, it doesn’t bring support for navigation in a deep zoom image. So you have to do it by yourself … or better use a Behavior for this features.
<UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" xmlns:TheOliver_Controls="clr-namespace:TheOliver.Controls" x:Class="DeepZoomMouseBehavior.MainPage" d:DesignHeight="300" d:DesignWidth="400"> <Grid x:Name="LayoutRoot" Background="White"> <TextBlock Text="Deep Zoom Sample" /> <MultiScaleImage x:Name="_msi" Source="Images/dzc_output.xml" Margin="0,12,0,0"> <i:Interaction.Behaviors> <TheOliver_Controls:DeepZoomBehavior /> </i:Interaction.Behaviors> </MultiScaleImage> </Grid> </UserControl>
// Copyright © Microsoft Corporation. All Rights Reserved. // This code released under the terms of the // Microsoft Public License (MS-PL, http://opensource.org/licenses/ms-pl.html.) using System.Windows; using System.Windows.Controls; using System.Windows.Input; using System.Windows.Interactivity; namespace TheOliver.Controls { public class DeepZoomBehavior : Behavior<MultiScaleImage> { MultiScaleImage _msi; Point _lastMousePos = new Point(); double _zoom = 1; bool _mouseButtonPressed = false; bool _mouseIsDragging = false; Point _dragOffset; Point _currentPosition; private double ZoomFactor { get { return _zoom; } set { _zoom = value; } } protected override void OnAttached() { _msi = this.AssociatedObject; _msi.MouseMove += delegate(object sender, MouseEventArgs e) { if (_mouseButtonPressed) { _mouseIsDragging = true; } _lastMousePos = e.GetPosition(_msi); }; _msi.MouseLeftButtonDown += delegate(object sender, MouseButtonEventArgs e) { _mouseButtonPressed = true; _mouseIsDragging = false; _dragOffset = e.GetPosition(_msi); _currentPosition = _msi.ViewportOrigin; }; _msi.MouseLeave += delegate(object sender, MouseEventArgs e) { _mouseIsDragging = false; }; _msi.MouseLeftButtonUp += delegate(object sender, MouseButtonEventArgs e) { _mouseButtonPressed = false; if (_mouseIsDragging == false) { bool shiftDown = (Keyboard.Modifiers & ModifierKeys.Shift) == ModifierKeys.Shift; ZoomFactor = 2.0; if (shiftDown) ZoomFactor = 0.5; Zoom(ZoomFactor, _lastMousePos); } _mouseIsDragging = false; }; _msi.MouseMove += delegate(object sender, MouseEventArgs e) { if (_mouseIsDragging) { Point newOrigin = new Point(); newOrigin.X = _currentPosition.X - (((e.GetPosition(_msi).X - _dragOffset.X) / _msi.ActualWidth) * _msi.ViewportWidth); newOrigin.Y = _currentPosition.Y - (((e.GetPosition(_msi).Y - _dragOffset.Y) / _msi.ActualHeight) * _msi.ViewportWidth); _msi.ViewportOrigin = newOrigin; } }; _msi.MouseWheel += (s,e) => { e.Handled = true; if (e.Delta > 0) { ZoomFactor = 1.2; } else { ZoomFactor = .80; } Zoom(ZoomFactor, _lastMousePos); }; } public void Zoom(double zoom, Point pointToZoom) { Point logicalPoint = _msi.ElementToLogicalPoint(pointToZoom); _msi.ZoomAboutLogicalPoint(zoom, logicalPoint.X, logicalPoint.Y); } } }
Last week I started my daily demo challenge. The Result, five simple, and easy to use samples for Silverlight.
18.03.2010 – Silverlight 3: Behavior - 3D Hover Effect // [Preview]
If you have any suggestions and comments, please feel free to comment.
In der heutigen Ausgabe von msdn tv – Nachrichten für Entwickler ist Jan Schenk nach kurzem Aufenthalt unter Palmen zu Gast bei der DNUG München, der DotNET Usergroup München (http://www.munichdot.net/). Im Interview ist Hardy Erlinger, Gründer der Münchner Usergroup und Leiter der INETA Deutschland (http://ineta-germany.org), und Gregor Biswanger, Silverlight-Abhängiger und Referent auf dem Usergroup-Treffen. Ausserdem gibt es in den Fast Facts of the Week wieder viel Neues zu Dariusz Parys Tutorialserie über Visual Studio 2010, der Beta 2 der Windows Server AppFabric, einer Webcastreihe von Holger Sirtl zum Thema Windows Azure Platform und der Microsoft Roadshow "Zwanzig Zehn" zum Launch von Visual Studio 2010 am 12. April. Ausserdem ein Terminhinweis auf Tom Wendels TechTalk-Runde quer durch Deutschland zum neuen Sharepoint 2010. Mit welcher Kopfbedeckung, welchen Versprechern und welchem Set msdn tv seine Zuschauer heute überrascht lässt sich nicht in Textform fassen. Um es mit wenigen Worten zu sagen: Die heutige Ausgabe ist die Überlänge wert. Die Gesamtspieldauer des Director’s Cut sind heute ganze 20 Minuten 38 Sekunden.
A common needed and used feature in Silverlight is the Fullscreen Mode. A feature to switch the current application from a hosted in browser to fullscreen mode. This features is interesting in scenarios like Point of Sales- or Games-Applications.
Normal Browser Mode
Full Screen Mode
Livepreview here
<UserControl x:Class="FullScreenBehavior.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" xmlns:TheOliver_Controls="clr-namespace:TheOliver.Controls" xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" d:DesignHeight="300" d:DesignWidth="400"> <Grid x:Name="LayoutRoot" Background="White"> <Button Content="Button" Height="23" HorizontalAlignment="Left" Margin="10,10,0,0" Name="button1" VerticalAlignment="Top" Width="75"> <i:Interaction.Triggers> <i:EventTrigger EventName="Click"> <TheOliver_Controls:FullScreenAction/> </i:EventTrigger> </i:Interaction.Triggers> </Button> <Rectangle Stroke="Black" Margin="155,113,141,110"> <i:Interaction.Triggers> <i:EventTrigger EventName="MouseLeftButtonUp"> <TheOliver_Controls:FullScreenAction/> </i:EventTrigger> </i:Interaction.Triggers> <Rectangle.Fill> <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> <GradientStop Color="Black" Offset="0"/> <GradientStop Color="White" Offset="1"/> </LinearGradientBrush> </Rectangle.Fill> </Rectangle> </Grid> </UserControl>
// Copyright © Microsoft Corporation. All Rights Reserved. // This code released under the terms of the // Microsoft Public License (MS-PL, http://opensource.org/licenses/ms-pl.html.) using System.Windows; using System.Windows.Interactivity; namespace TheOliver.Controls { public class FullScreenAction : TargetedTriggerAction<FrameworkElement> { protected override void Invoke(object o) { Application.Current.Host.Content.IsFullScreen = !Application.Current.Host.Content.IsFullScreen; } } }
Solution download
Behaviors are great new feature in Silverlight 3 (or better in Blend 3) for adding “features” to a control without coding. My favorite sample is a hover effect, that applies when a mouse enters a control.
Live-Preview
XAML-Code:
<UserControl x:Class="Hover3DBehavior.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" xmlns:TheOliver_Controls="clr-namespace:TheOliver.Controls" d:DesignHeight="300" d:DesignWidth="400" xmlns:dataInput="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data.Input"> <Grid x:Name="LayoutRoot" Background="White"> <Button Content="Button" Height="23" HorizontalAlignment="Left" Margin="89,78,0,0" Name="button1" VerticalAlignment="Top" Width="75"> <i:Interaction.Behaviors> <TheOliver_Controls:Hover3DBehavior /> </i:Interaction.Behaviors> </Button> <dataInput:Label Height="50" HorizontalAlignment="Left" Margin="274,64,0,0" Name="label1" VerticalAlignment="Top" Width="100" Content="Hello World"> <i:Interaction.Behaviors> <TheOliver_Controls:Hover3DBehavior /> </i:Interaction.Behaviors> </dataInput:Label> <RadioButton Content="RadioButton" Height="16" HorizontalAlignment="Left" Margin="12,133,0,0" Name="radioButton1" VerticalAlignment="Top"> <i:Interaction.Behaviors> <TheOliver_Controls:Hover3DBehavior /> </i:Interaction.Behaviors> </RadioButton> </Grid> </UserControl>
Source-Code:
// Copyright © Microsoft Corporation. All Rights Reserved. // This code released under the terms of the // Microsoft Public License (MS-PL, http://opensource.org/licenses/ms-pl.html.) using System.ComponentModel; using System.Windows; using System.Windows.Input; using System.Windows.Interactivity; using System.Windows.Media; using System.Windows.Media.Animation; namespace TheOliver.Controls { public class Hover3DBehavior : Behavior<UIElement> { PlaneProjection _planeProjection; public Hover3DBehavior() : base() { } Storyboard _hoverMe; Storyboard _unhoverMe; public double ZHoverValue { get { return (double)GetValue(ZHoverValueProperty); } set { SetValue(ZHoverValueProperty, value); } } public static readonly DependencyProperty ZHoverValueProperty = DependencyProperty.Register("ZHoverValue", typeof(double), typeof(Hover3DBehavior), new PropertyMetadata(500.0, null)); public int HoverDurationMilliseconds { get { return (int)GetValue(HoverDurationMillisecondsProperty); } set { SetValue(HoverDurationMillisecondsProperty, value); } } public static readonly DependencyProperty HoverDurationMillisecondsProperty = DependencyProperty.Register("HoverDurationMilliseconds" , typeof(int) , typeof(Hover3DBehavior), new PropertyMetadata(200, null)); #region Overrides protected override void OnAttached() { base.OnAttached(); _planeProjection = new PlaneProjection(); this.AssociatedObject.Projection = _planeProjection; if (!DesignerProperties.GetIsInDesignMode(this)) { _hoverMe = new Storyboard(); DoubleAnimation da1 = new DoubleAnimation(); _hoverMe.Children.Add(da1); da1.Duration = new Duration(new System.TimeSpan(0, 0, 0, 0, HoverDurationMilliseconds)); da1.To = this.ZHoverValue; Storyboard.SetTarget(da1, this.AssociatedObject); Storyboard.SetTargetProperty(da1, new PropertyPath("(UIElement.Projection).(PlaneProjection.LocalOffsetZ)")); DoubleAnimation da2 = new DoubleAnimation(); BounceEase be2 = new BounceEase(); be2.EasingMode = EasingMode.EaseOut; be2.Bounces = 3; da2.EasingFunction = be2; _unhoverMe = new Storyboard(); _unhoverMe.Children.Add(da2); da2.Duration = new Duration(new System.TimeSpan(0, 0, 0, 0, 1000)); da2.To = 0.0; Storyboard.SetTarget(da2, this.AssociatedObject); Storyboard.SetTargetProperty(da2, new PropertyPath("(UIElement.Projection).(PlaneProjection.LocalOffsetZ)")); if ((this.AssociatedObject as FrameworkElement).Resources.Contains("hoverme")) { (this.AssociatedObject as FrameworkElement).Resources.Remove("hoverme"); } (this.AssociatedObject as FrameworkElement).Resources.Add("hoverme", _hoverMe); if ((this.AssociatedObject as FrameworkElement).Resources.Contains("unhoverme")) { (this.AssociatedObject as FrameworkElement).Resources.Remove("unhoverme"); } (this.AssociatedObject as FrameworkElement).Resources.Add("unhoverme", _unhoverMe); } this.AssociatedObject.MouseEnter += AssociatedObject_MouseEnter; this.AssociatedObject.MouseLeave += AssociatedObject_MouseLeave; } protected override void OnDetaching() { base.OnDetaching(); this.AssociatedObject.Projection = null; _planeProjection = null; this.AssociatedObject.MouseEnter -= AssociatedObject_MouseEnter; this.AssociatedObject.MouseLeave -= AssociatedObject_MouseLeave; } #endregion #region Events void AssociatedObject_MouseLeave(object sender, MouseEventArgs e) { _unhoverMe.Begin(); } void AssociatedObject_MouseEnter(object sender, MouseEventArgs e) { //FrameworkElement e1 = this.AssociatedObject as FrameworkElement; //if (e1.Parent is Panel) //{ // Panel p = e1.Parent as Panel; // if (p != null) // { // UIElement element = this.AssociatedObject; // element.SetValue(UIElement. // p.Children.Remove(element); // p.Children.Add(element); // } //} _hoverMe.Begin(); } #endregion } }
Download-SampleCode
Auf www.paris-26-gigapixels.com befindet sich das derzeit angeblich größte Digitalfoto. Aus 2346 Bilden wurde die Skyline von Paris zusammengesetzt.
Schon sehr beeindruckend. Allerdings frage ich mich warum man sich so einen riesigen Aufwand mit dem Zusammensetzen der Bilder macht, aber null Aufwand für einen gescheiten Player, der das Bild ordentlich darstellt.
Die Navigation ist sehr gewöhnungsbedürftig, übliche Verfahren wie Doppelklicks oder Mausrad funktionieren nicht. Entgegen allen üblichen Navigationen wandert man nach rechts in dem man die Maus nach links bewegt. Darüber hinaus explodiert quasi Speicherverbrauch der Webseite.
Wer so etwas auf einfache Art und Weise selber machen möchte, ohne wirklich selber viel Aufwand zu haben, kriegt dazu von Microsoft kostenlose Werkzeuge an die Hand gelegt.
Mit der Windows Live Fotogallerie gibt es eine sehr gute Bilderverarbeitung die für jeden Hobby- und semiprofessionellen Fotografen ausreicht. Die Fotogallerie hat eine tolle Funktion zum automatischen Zusammensetzen von vielen Bildern, die allerdings gewisse Überschneidungen haben müssen.
Hat man dann ein sehr großes Bild, dann kann man dieses mit dem Deep Zoom Composer so vorbereiten, das es sehr schnell von jedem Browser geladen werden kann. Diese Technik basiert auf Silverlight.
Die Tools sind kostenlos und gibt es hier:
Windows Live Fotogallerie
Deep Zoom Composer
Ein weiteres Tool das etwas technischer ist: Microsoft Research Image Composite Editor
An interesting control is a Image Stack, where Images are stacked on top of each other. Normally you remove the image on top and put it to the back. So I did. If you double-click the stack an animation move the image to the back.
Live-Demo here
<UserControl x:Class="ImageStack.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" d:DesignHeight="321" d:DesignWidth="416" xmlns:my="clr-namespace:TheOliver.Controls"> <Grid x:Name="LayoutRoot" Background="White"> <my:ImageStack Margin="12" x:Name="imageStack1" Background="Gray" > <Image Source="/ImageStack;Component/Assets/1.jpg" /> <Image Source="/ImageStack;Component/Assets/2.jpg" /> <Image Source="/ImageStack;Component/Assets/3.jpg" /> <Image Source="/ImageStack;Component/Assets/4.jpg" /> <Image Source="/ImageStack;Component/Assets/5.jpg" /> </my:ImageStack> </Grid> </UserControl>
// Copyright © Microsoft Corporation. All Rights Reserved. // This code released under the terms of the // Microsoft Public License (MS-PL, http://opensource.org/licenses/ms-pl.html.) using System; using System.Linq; using System.Windows; using System.Windows.Controls; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Media.Effects; using System.Windows.Threading; namespace TheOliver.Controls { public class ImageStack : Panel { public ImageStack() { _doubleClickTimer = new DispatcherTimer(); _doubleClickTimer.Interval = new TimeSpan(0, 0, 0, 0, DoubleClickSpeedInMS); _doubleClickTimer.Tick += (s, e) => { _clickCount = 0; _doubleClickTimer.Stop(); }; this.MouseLeftButtonUp += (s, e) => { if (_clickCount == 1) { // Doubleclick detected HideCurrentImage(); } else { _clickCount++; _doubleClickTimer.Start(); } }; _hideStoryboard.Completed += (s, e) => { this.Children.Remove(_removedImage); this.Children.Insert(0, _removedImage); ShowNextImage(); }; _showStoryboard.Completed += (s, e) => { _storyboardIsActive = false; }; } Random _random = new Random(); int _clickCount; DispatcherTimer _doubleClickTimer; Storyboard _hideStoryboard = new Storyboard(); Storyboard _showStoryboard = new Storyboard(); Image _removedImage; bool _storyboardIsActive = false; double _newX; double _newY; Size _finalSize; private void ShowNextImage() { TimeSpan duration = new TimeSpan(0, 0, 0, 0, AnimationInMS); // Part 2 DoubleAnimation xa2 = new DoubleAnimation(); xa2.Duration = duration; xa2.To = -_newX; DoubleAnimation ya2 = new DoubleAnimation(); ya2.Duration = duration; ya2.To = -_newY; _showStoryboard.Stop(); _showStoryboard.Children.Clear(); _showStoryboard.Duration = duration; _showStoryboard.Children.Add(xa2); _showStoryboard.Children.Add(ya2); TransformGroup tg = _removedImage.RenderTransform as TransformGroup; TranslateTransform tt2 = new TranslateTransform(); tg.Children.Add(tt2); _removedImage.RenderTransform = tg; Storyboard.SetTarget(xa2, tt2); //set Animation Target Storyboard.SetTargetProperty(xa2, new PropertyPath("X")); // set Animation TargetProperty Storyboard.SetTarget(ya2, tt2); Storyboard.SetTargetProperty(ya2, new PropertyPath("Y")); if (this.Resources.Contains("showme")) { this.Resources.Remove("showme"); } this.Resources.Add("showme", _showStoryboard); _showStoryboard.Begin(); } bool _layouted = false; protected override Size ArrangeOverride(Size finalSize) { _finalSize = finalSize; if (!_layouted) { LayoutImages(_finalSize); _layouted = true; } return base.ArrangeOverride(finalSize); } private void HideCurrentImage() { if (_storyboardIsActive) { return; } _storyboardIsActive = true; _removedImage = this.Children[this.Children.Count - 1] as Image; if (_removedImage != null) { TimeSpan duration = new TimeSpan(0, 0, 0, 0, AnimationInMS); double angle = _random.Next(360); _newX = Math.Sin(angle) * this.RenderSize.Width; _newY = Math.Cos(angle) * this.RenderSize.Height; _hideStoryboard.Stop(); _hideStoryboard.Children.Clear(); // Part 1 DoubleAnimation xa1 = new DoubleAnimation(); xa1.Duration = duration; xa1.To = _newX; DoubleAnimation ya1 = new DoubleAnimation(); ya1.Duration = duration; ya1.To = _newY; _hideStoryboard.Duration = duration; _hideStoryboard.Children.Add(xa1); _hideStoryboard.Children.Add(ya1); TransformGroup tg = _removedImage.RenderTransform as TransformGroup; TranslateTransform tt = new TranslateTransform(); tg.Children.Add(tt); _removedImage.RenderTransform = tg; Storyboard.SetTarget(xa1, tt); Storyboard.SetTargetProperty(xa1, new PropertyPath("X")); Storyboard.SetTarget(ya1, tt); Storyboard.SetTargetProperty(ya1, new PropertyPath("Y")); if (this.Resources.Contains("hideme")) { this.Resources.Remove("hideme"); } this.Resources.Add("hideme", _hideStoryboard); _hideStoryboard.Begin(); } } private Size LayoutImages(Size finalSize) { var images = this.Children.OfType<Image>(); Random rnd = new Random(); foreach (var image in images) { // Drop Shadow Effect if (ShowDropShadowEffect) { DropShadowEffect dse = new DropShadowEffect(); dse.ShadowDepth = 0.3; image.Effect = dse; } // Center image image.VerticalAlignment = System.Windows.VerticalAlignment.Center; image.HorizontalAlignment = System.Windows.HorizontalAlignment.Center; TransformGroup tg = new TransformGroup(); // Scale to fit the finalsize * 90% image.Stretch = Stretch.Uniform; image.Width = finalSize.Width * ResizeFactor; image.Height = finalSize.Height * ResizeFactor; image.Margin = new Thickness( (finalSize.Width - image.Width) / 2, (finalSize.Height - image.Height) / 2, (finalSize.Width - image.Width) / 2, (finalSize.Height - image.Height) / 2); // Rotate image RotateTransform rt = new RotateTransform(); rt.Angle = 90 - rnd.Next(180); rt.CenterX = image.Width / 2; rt.CenterY = image.Height / 2; tg.Children.Add(rt); image.RenderTransform = tg; } return finalSize; } #region Properties public double ResizeFactor { get { return (double)GetValue(ResizeFactorProperty); } set { SetValue(ResizeFactorProperty, value); } } public static readonly DependencyProperty ResizeFactorProperty = DependencyProperty.Register( "ResizeFactor", typeof(double), typeof(ImageStack), new PropertyMetadata(0.5, OnValueChanged)); private static void OnValueChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) { ImageStack stack = sender as ImageStack; stack.InvalidateArrange(); } public bool ShowDropShadowEffect { get { return (bool)GetValue(ShowDropShadowEffectProperty); } set { SetValue(ShowDropShadowEffectProperty, value); } } public static readonly DependencyProperty ShowDropShadowEffectProperty = DependencyProperty.Register( "ShowDropShadowEffect", typeof(bool), typeof(ImageStack), new PropertyMetadata(true, OnValueChanged)); public int DoubleClickSpeedInMS { get { return (int)GetValue(DoubleClickSpeedInMSProperty); } set { SetValue(DoubleClickSpeedInMSProperty, value); } } public static readonly DependencyProperty DoubleClickSpeedInMSProperty = DependencyProperty.Register( "DoubleClickSpeedInMS", typeof(int), typeof(ImageStack), new PropertyMetadata(500, OnDoubleClickSpeedChanged)); private static void OnDoubleClickSpeedChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) { ImageStack stack = sender as ImageStack; stack._doubleClickTimer.Stop(); stack._doubleClickTimer.Interval = new TimeSpan(0, 0, 0, 0, (int)e.NewValue); } public bool EnableDragging { get { return (bool)GetValue(EnableDraggingProperty); } set { SetValue(EnableDraggingProperty, value); } } public static readonly DependencyProperty EnableDraggingProperty = DependencyProperty.Register( "EnableDragging", typeof(bool), typeof(ImageStack), new PropertyMetadata(false)); public int AnimationInMS { get { return (int)GetValue(AnimationInMSProperty); } set { SetValue(AnimationInMSProperty, value); } } public static readonly DependencyProperty AnimationInMSProperty = DependencyProperty.Register( "AnimationInMS", typeof(int), typeof(ImageStack), new PropertyMetadata(125)); #endregion } } Download Sourcecode