Archiv | Custom Controls RSS for this section

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 Phone

Advanced 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>
Xaml-Code

image

Abb.: Control in Action

Viele weitere Beispiel findet ihr unter den Ouellen

Quellen:

Coding4Fun Toolkit
 
Getting Started with the Coding4Fun toolkit MetroFlow Control
 

Navigation 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);
}
Danach sollte die Class erstellt werden
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));
    }
}
Nun noch im ViewModel integrieren
public interface INavigable
{
    INavigationService NavigationService { get; set; }
}
und ein Navigator im ViewModel
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);
        }
    }
}
Hier noch ein wenig wie das im XAML eingesetzt wird:
<navigation:Page x:Class="SLNavigation.Page1"
           xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
           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}"
    >
Quelle:

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

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.

image

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.

image

Nun noch den Backround Service einbauen und fertig ist Splash Screen.

clip_image001

Abb.: Fertiges Control im Einsatz

Quelle:

How to create Splash Screen with Progress Bar in Windows Phone 7

Fokus 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();
    }
}
Und hier der XAML Beispielcode:
<i:Interaction.Triggers>
    <i:EventTrigger>
        <Behaviors:FocusOnEvent TargetName="TitleTextBox" />
    </i:EventTrigger>
</i:Interaction.Triggers>
Quelle:
Mark Monster Blog

 

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:

Bitdisaster

 

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 control

HubTile 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.

image

Diese Flipping und Expand States werten ein App wirklich auf.

image

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 States

HubTile 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;
    }
Eine Action Methode:
private void HubTileTapAction(string param)
{
    string message = string.Format("{0} was tapped", param);
    MessageBox.Show(message);
}
Und ein wenig Code und XAML:
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>
Und hier das Ergebnis:
imageimage
Quelle:
WindowsPhoneGeek