ApplicationBar in neuen Gewand
Auf Windows Phone Geek ist ein Post über eine Advanced Application Bar erschienen. Mit diesem Control kann man nun auch die Visibility und ICommand benutzen, was natürlich die MVVM Pattern nutzenden Entwickler freuen wird.
Mit ein paar Zeilen Code ist eine ansprechende App Bar mit dem oben beschriebenen Support verfügbar.
<
Sh:AdvancedApplicationBar
>
<
Sh:AdvancedApplicationBarIconButton
IsEnabled
=
"{Binding AppBarIconButtonEnabled}"
Text
=
"{Binding AppBarIconButtonText}"
IconUri
=
"{Binding IconUri}"
Click
=
"AdvancedApplicationBarIconButton_Click"
/>
<
Sh:AdvancedApplicationBarIconButton
Text
=
"{Binding AppBarIconButtonText}"
IconUri
=
"{Binding AppBarIconButtonText}"
Visibility
=
"{Binding Visibility}"
Command
=
"{Binding DeleteCommand}"
CommandParameter
=
"42"
/>
<
Sh:AdvancedApplicationBarIconButton
Text
=
"static text"
IconUri
=
"/Images/appbar.feature.settings.rest.png"
/>
<
Sh:AdvancedApplicationBarMenuItem
Text
=
"MenuItemTxt"
/>
</
Sh:AdvancedApplicationBar
>
Besonders Cool ist aber der Support für Panorama bzw. Pivot Control. So kann jetzt innerhalb jedes Tab eine Application Bar mit unterschiedlichen Buttons aufgebaut werden. Für mich steht fest dieses Control kommt in meine nächste Entwicklung.
Quelle:
Advanced ApplicationBar for Windows PhoneAdvanced ApplicationBar for Windows Phone
MetroFlow ein Control der neuen Generation
Wer Apps mit vielen Bildern oder Video Anzeige hat sollte sich mal das neue MetroFlow Control vom Coding4Fun toolkit beschäftigen. Auf WindowsPhoneGeek, wir in einem ersten Beispiel beschrieben wie dieses Control funktioniert.
Alles was benötigt wird ist die neuste Version des Coding4Fun Toolkits.
Mit nur wenigen Zeilen Code ist schon eine erste Anzeige des Controls möglich,
<
c4f:MetroFlow
>
<
c4f:MetroFlowData
Title
=
"Sample 1"
/>
<
c4f:MetroFlowData
ImageUri
=
"Images/bmw1.jpg"
Title
=
"BMW 1"
/>
<
c4f:MetroFlowData
ImageUri
=
"Images/bmw1.jpg"
/>
</
c4f:MetroFlow
>
Abb.: Control in Action
Viele weitere Beispiel findet ihr unter den Ouellen
Quellen:
Coding4Fun Toolkit Getting Started with the Coding4Fun toolkit MetroFlow ControlNavigation mit Service
Der NavigationService im MVVM ist für die Steuerung zwischen Views und ViewModel. Wie man diesen Service erstellt und einsetzt, dass kann man im Rob Garfoot’s Blog in seinem aktuellen Post lesen.
Hier das grundliegende Interface:
public
interface
INavigationService
{
void
Navigate(
string
url);
}
public
class
NavigationService : INavigationService
{
private
readonly
System.Windows.Navigation.NavigationService _navigationService;
public
NavigationService(System.Windows.Navigation.NavigationService navigationService)
{
_navigationService = navigationService;
}
public
void
Navigate(
string
url)
{
_navigationService.Navigate(
new
Uri(url, UriKind.RelativeOrAbsolute));
}
}
public
interface
INavigable
{
INavigationService NavigationService {
get
;
set
; }
}
public
static
class
Navigator
{
public
static
INavigable GetSource(DependencyObject obj)
{
return
(INavigable)obj.GetValue(SourceProperty);
}
public
static
void
SetSource(DependencyObject obj, INavigable value)
{
obj.SetValue(SourceProperty, value);
}
public
static
readonly
DependencyProperty SourceProperty =
DependencyProperty.RegisterAttached(
"Source"
,
typeof
(INavigable),
typeof
(Navigator),
new
PropertyMetadata(OnSourceChanged));
private
static
void
OnSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
Page page = (Page) d;
page.Loaded += PageLoaded;
}
private
static
void
PageLoaded(
object
sender, RoutedEventArgs e)
{
Page page = (Page)sender;
INavigable navSource = GetSource(page);
if
(navSource !=
null
)
{
navSource.NavigationService =
new
NavigationService(page.NavigationService);
}
}
}
<
navigation:Page
x:Class
=
"SLNavigation.Page1"
mc:Ignorable
=
"d"
xmlns:navigation
=
"clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"
xmlns:SLNavigation
=
"clr-namespace:SLNavigation"
d:DesignWidth
=
"640"
d:DesignHeight
=
"480"
Title
=
"Page1 Page"
SLNavigation:Navigator.Source
=
"{Binding}"
>
Augmented Reality XAML Control für WP7 und WinRT
Ich habe ja schon über Augmented Reality Theorie berichtet, aber jetzt hat Morten Nielsen in seinem Blog einen Post erstellt, wie man ein XAML Control erstellt. Das Besondere daran ist, das es nicht nur das Windows Phone unterstützt sondern auch die kommende Windows Version 8 oder besser bekannt für Entwickler Win RT.
Mit diesem Control baue ich eine Informations App für Industrieanlagen. Nun zeige ich noch einige Codeauschnitte:
<ar:ARPanel> <TextBlock Text="North" ar:ARPanel.Direction="0,0" /> <TextBlock Text="East" ar:ARPanel.Direction="0,90" /> <TextBlock Text="South" ar:ARPanel.Direction="0,180" /> <TextBlock Text="West" ar:ARPanel.Direction="0,270" /> <TextBlock Text="Up" ar:ARPanel.Direction="90,0" /> <TextBlock Text="Down" ar:ARPanel.Direction="-90,0" /> </ar:ARPanel>
Abb.: AR Control Panel in Xaml
Nachfolgend noch ein Beispiel wie man den Motion Sensor in Win RT und Windows Phone gemeinsam nutzen kann.
#if WINDOWS_PHONE if (Microsoft.Devices.Sensors.Motion.IsSupported) { motion = new Microsoft.Devices.Sensors.Motion(); motion.CurrentValueChanged += motion_CurrentValueChanged; motion.Start(); #elif WINRT motion = Windows.Devices.Sensors.OrientationSensor.GetDefault(); if (motion != null) { motion.ReadingChanged += motion_CurrentValueChanged; #endif } else { throw new InvalidOperationException("Motion sensor not supported on this device"); } #endif
Quellen:
Augmented Reality on Windows Phone and Windows 8 Metro style apps
Splash Screen mit ProgressBar und Backroundworker
Dhananjay Kumar hat auf seinem Blog debug mode….. einen Post erstellt, mit einem Designvorschlag für einen Splash Screen mit ProgressBar. Diese Vorgehensweise erlaubt es dem Entwickler seine benötigten Daten für die App geschickt zu verstecken und somit den User nicht nervt mit ständigen Nachladen von Daten. Diese vorgehensweise ist meist aber nur sinnvoll wenn es sich um eine Online App handelt.
Abb.: Aufbau des Design Vorschlags
Der Aufbau ist als Usercontrol implementiert, und recht einfach nachvollziehbar.
<Grid x:Name=“LayoutRoot“ Height=“800″ Width=“640″>
<Image Source=“waitsymbol.jpg“
Margin=“0,0,0,0″
VerticalAlignment=“Top“
Height=“650″
HorizontalAlignment=“Left“
Width=“400″
Stretch=“Fill“/>
<TextBlock
Text=“loading….“
HorizontalAlignment=“Left“
Style=“{StaticResource PhoneTextTitle2Style}“
Margin=“185,656,0,97″
/>
<ProgressBar x:Name=“SpalshScreenProgressbar“
Width=“380″
HorizontalAlignment=“Left“
IsIndeterminate=“True“
Margin=“49,707,0,74″ />
</Grid>
Das Control wird einfach in ein PopUp als Child Objekt hinzugefügt.
Nun noch den Backround Service einbauen und fertig ist Splash Screen.
Abb.: Fertiges Control im Einsatz
Quelle:
How to create Splash Screen with Progress Bar in Windows Phone 7Fokus Trigger in Silverlight
Über Mark Monster hatte ich ja schon öfter mal einen Beitrag, heute beschreibt er wie man einen Focus Trigger in Silverlight aufbaut. Einen klassische Trigger sieht wie folgt aus:
public
class
FocusOnEvent : TargetedTriggerAction<Control>
{
protected
override
void
Invoke(
object
parameter)
{
Target.Focus();
}
}
Dieser ist schnell implementiert. Aber sinnvoller ist ein Default Trigger aus dem TargetTriggerAction zu implementieren, dieser könnte wie folgt aussehen:
[DefaultTrigger(
typeof
(FrameworkElement),
typeof
(EventTrigger),
"Loaded"
)]
public
class
FocusOnEvent : TargetedTriggerAction<Control>
{
protected
override
void
Invoke(
object
parameter)
{
Target.Focus();
}
}
<
i:Interaction.Triggers
>
<
i:EventTrigger
>
<
Behaviors:FocusOnEvent
TargetName
=
"TitleTextBox"
/>
</
i:EventTrigger
>
</
i:Interaction.Triggers
>
Codesnippets für MVVM RelayCommand
Wer viel mit dem Galasoft MVVM Light Framework arbeitet kann sich die Arbeit mit Commands vereinfachen. Jan Hannemann hat auf seinem Blog einen Post erstellt mit Codesnippets für eben diese Definition von RelayCommands.
<?xml version="1.0" encoding="utf-8" ?> 2: <CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet"> 3: <CodeSnippet Format="1.0.0"> 4: <Header> 5: <Title>RelayCommand</Title> 6: <Shortcut>relaycmd</Shortcut> 7: <Description>Define a RelayCommand</Description> 8: <Author>Jan Hannemann</Author> 9: <SnippetTypes> 10: <SnippetType>Expansion</SnippetType> 11: </SnippetTypes> 12: </Header> 13: <Snippet> 14: <Declarations> 15: <Literal> 16: <ID>CMD</ID> 17: <ToolTip>Command Property</ToolTip> 18: <Default>Command</Default> 19: </Literal> 20: <Literal> 21: <ID>CMDF</ID> 22: <ToolTip>Command Field</ToolTip> 23: <Default>command</Default> 24: </Literal> 25: </Declarations> 26: <Code Language="csharp"> 27: <![CDATA[ 28: private RelayCommand _$CMDF$; 29: public RelayCommand $CMD$ 30: { 31: get 32: { 33: return _$CMDF$; 34: } 35: } 36: 37: /// <summary> 38: /// Checks whether the $CMD$ command is executable 39: /// </summary> 40: private bool Can$CMD$() 41: { 42: return true; 43: } 44: 45: /// <summary> 46: /// Executes the $CMD$ command 47: /// </summary> 48: private void Exec$CMD$() 49: { 50: throw new NotImplementedException(); 51: } 52: 53: //cut and paste this line to your ctor 54: _$CMDF$ = new RelayCommand(Exec$CMD$, Can$CMD$); 55: $end$]]> 56: </Code> 57: </Snippet> 58: </CodeSnippet> 59: </CodeSnippets>
Diese Codesnippets erleichtern die tägliche Arbeit doch ein wenig, und das Leben des Entwicklers wird wieder etwas schöner.
Quelle:
Bing Maps Pushpin Optimierung
Über das Bing Maps Control in WP7 habe ich ja schon einige Posts geschrieben, heute geht es darum ein Clustering Pattern für Mengen von Pins zu erstellen.
Colin Eberhardt von ScottLogic hat in einem Post dieses Problem angegangen und dokumentiert.
Über eine Container Pattern Class wird diese Funktion implementiert.
// <summary>
/// Clusters the given pins on the supplied map
/// </summary>
public PushpinClusterer(Map map, List<Pushpin> pins, DataTemplate clusterTemplate)
{ _map = map; _pins = pins; ClusterTemplate = clusterTemplate; _map.ViewChangeEnd += (s, e) => RenderPins(); }
/// <summary> /// Re-render the pushpins based on the current zoom level /// </summary>
private void RenderPins()
{ List<PushpinContainer> pinsToAdd = new List<PushpinContainer>();
// consider each pin in turn foreach (var pin in _pins)
{ var newPinContainer = new PushpinContainer(pin, _map.LocationToViewportPoint(pin.Location));
bool addNewPin = true;
// determine how close they are to existing pins foreach(var pinContainer in pinsToAdd)
{ double distance = ComputeDistance(pinContainer.ScreenLocation, newPinContainer.ScreenLocation);
// if the distance threshold is exceeded, do not add this pin, instead // add it to a cluster
if (distance < DistanceThreshold) { pinContainer.Merge(newPinContainer); addNewPin = false; break; } }
if (addNewPin) { pinsToAdd.Add(newPinContainer); } }
// asynchronously update the map
_map.Dispatcher.BeginInvoke(() => { _map.Children.Clear();
foreach (var projectedPin in pinsToAdd.Where(pin => PointIsVisibleInMap(pin.ScreenLocation, _map)))
{ _map.Children.Add(projectedPin.GetElement(ClusterTemplate)); } });
}
Abb.: Auszug Quellcode
Falls Ihr solche Problematik auch habt dann sollte der Post auch sehr interessieren.
Quelle:
Pushpin Clustering with the Windows Phone 7 Bing Map controlHubTile Visual States Beispiel
Weil ich gerade sowieso damit in meiner aktuellen APP rumspiele, fand ich den Post auf WindowsPhoneGeek Blog sehr interessant.
Es geht um HubTiles und dem Visual State.
Diese Flipping und Expand States werten ein App wirklich auf.
Abb: Verschiedene State
Mit den Windows Phone Toolkit sind das nur wenige Zeilen Code. Hier ein Beispiel Code:
<
StackPanel
x:Name
=
"ContentPanel"
Grid.Row
=
"1"
Margin
=
"12,0,12,0"
Orientation
=
"Vertical"
>
<
toolkit:HubTile
x:Name
=
"hubTile"
Background
=
"Green"
Source
=
"wpglogo.png"
Title
=
"Hold Here"
Message
=
"This is HubTile message!"
Margin
=
"10"
/>
<
Button
x:Name
=
"btnGoToExpanded"
Content
=
" Go To Expanded State"
Click
=
"btnGoToExpanded_Click"
/>
<
Button
x:Name
=
"btnGoToSemiexpanded"
Content
=
"Go To Semiexpanded State"
Click
=
"btnGoToSemiexpanded_Click"
/>
<
Button
x:Name
=
"btnGoToFlipped"
Content
=
"Go To Flipped State"
Click
=
"btnGoToFlipped_Click"
/>
<
Button
x:Name
=
"btnGoToCollapsed"
Content
=
"Go To Collapsed State"
Click
=
"btnGoToCollapsed_Click"
/>
</
StackPanel
>
Und hier die Steuerung des Visual State Manager in C#:
private
void
btnGoToSemiexpanded_Click(
object
sender, RoutedEventArgs e)
{
VisualStateManager.GoToState(
this
.hubTile,
"Semiexpanded"
,
true
);
}
Quelle:
WindowPhoneGeek Blog How to Programmatically Switch between the HubTile Visual StatesHubTile Event Binding mit MVVM Light Toolkit
HubTiles sind im neuen WP7 Mango noch deutlich aufgewertet worden und der Developer hat viel mehr Möglichkeiten die UI seiner APP zu verbessern. Viele Entwickler benutzen wie auch ich das MVVM Light Toolkit um MVVM in der APP umzusetzen. Um nun im HubTile EventToCommand Binding richtig umzusetzen ist auf WindowsPhoneGeek ein Post erschienen wo beschrieben wird wie einfach das ist.
Ein Command erstellen:
public
ICommand TapCommand
{
get
;
set
;
}
private
void
HubTileTapAction(
string
param)
{
string
message =
string
.Format(
"{0} was tapped"
, param);
MessageBox.Show(message);
}
public
MainPage()
{
InitializeComponent();
ICommand tapCommand =
new
RelayCommand<
string
>(
this
.HubTileTapAction);
//...
}
<
ListBox
Grid.Row
=
"0"
x:Name
=
"tileList"
>
<
ListBox.ItemsPanel
>
<
ItemsPanelTemplate
>
<
toolkit:WrapPanel
Orientation
=
"Horizontal"
/>
</
ItemsPanelTemplate
>
</
ListBox.ItemsPanel
>
<
ListBox.ItemTemplate
>
<
DataTemplate
>
<
toolkit:HubTile
Title
=
"{Binding Title}"
Margin
=
"3"
Notification
=
"{Binding Notification}"
DisplayNotification
=
"{Binding DisplayNotification}"
Message
=
"{Binding Message}"
GroupTag
=
"{Binding GroupTag}"
Source
=
"{Binding ImageUri}"
>
<
i:Interaction.Triggers
>
<
i:EventTrigger
EventName
=
"Tap"
>
<
cmd:EventToCommand
Command
=
"{Binding TapCommand}"
CommandParameter
=
"{Binding Title}"
/>
</
i:EventTrigger
>
</
i:Interaction.Triggers
>
</
toolkit:HubTile
>
</
DataTemplate
>
</
ListBox.ItemTemplate
>
</
ListBox
>