Archiv | MVVM RSS for this section

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:

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

 

Cross-Platform Projectbeispiel

Damit man nicht alles neu programmieren muss, wenn man für WP7 oder WPF entwickelt, zeigt ein Post auf der Website The Code Project wie eine Solution aufgebaut werden sollte.

Abb.: Youtube Video eine Xaml Finance App

Diese Anwendung ist verfügbar für WP7, Silverlight, und WPF.

XAMLFinanceSilverlightSmall.jpg

Abb.: Silverlight Version Online

Es wird wirklich alles beleuchtet in diesem Post, wie z.B. die Marktverteilung von Xaml Anwendung. Sehr gut wird erklärt wie Projekteigenschaften angepasst werden müssen und wie die Views und die Models aufgebaut werden können.

XamlFinanceWPFDesign.png

 

Quelle:

XAMLFinance – A Cross-platform WPF, Silverlight & WP7 Application

Metro Style Grundlagen

Da Microsoft nun auch mit Windows 8 den Metro Design Style einführt, ist es für uns Entwickler Zeit sich mit diesem Style für Oberflächen auseinanderzusetzen. Für WP7 Entwickler schon ein fast ein alter Hut, ist für Windows Entwickler dieser Style wohl für die meisten neu.

Auf codefest.at ist ein Beitrag erschienen, wie man sich mit diesem Neuling in der Windows Welt am besten anfreundet. Es entstehen ja in Zukunft immer mehr auf Tablets basierende Systeme.

win8_touch

Microsoft hat ja nun auch schon ein wenig Erfahrung gesammelt mit den Surface Tisch Systemen, so verwundert es nicht das diese Technik nun auch auf Windows 8 Einzug hält.

win8_touch_demo_8_mouse

Quellen:

codefest.at
buildwindows
 

 

 

Neue Ideen für MVVM Pattern

Erno de Weerd, hat einen neuen Ansatz des MVVM Patterns in seinem Blog infoSupport beschrieben. Hier wird mit Hilfe von Reflections eine Implementierung geschaffen die flexibler und robuster auf Veränderungen des Views und des Models reagiert und somit für den Entwickler Zeit spart.

using System;
using System.ComponentModel;
using System.Linq.Expressions;
using System.Reflection;
using System.Windows;

namespace MVVM
{
public class ViewModelBase<T> : INotifyPropertyChanged
{
public App Application
{
get
{
return App.Current as App;
}
}

#region INotifyPropertyChanged Implementation
public event PropertyChangedEventHandler PropertyChanged;

protected void NotifyPropertyChanged<TProperty>(
Expression<Func<T, TProperty>> propertyExpression)
{
MemberExpression memberExpression = propertyExpression.Body
as System.Linq.Expressions.MemberExpression;
if (memberExpression == null || (memberExpression != null &&
memberExpression.Member.MemberType != MemberTypes.Property))
{
throw new ArgumentException(
„The specified expression does not represent a valid property“);
}
OnPropertyChanged(memberExpression.Member.Name);
}

protected void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler p = PropertyChanged;
if (p != null)
{
p(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
}
}

Abb.: Base Class für das ViewModel

Sprachen unabhängig zu sein hat bei der App Entwicklung einen Marktentscheidenen Vorteil und ist rechtzeitig mit einzuplanen bei der Entwicklung.

using System;
using System.ComponentModel;
using System.Linq.Expressions;
using System.Reflection;
using System.Windows;

namespace MVVM
{
public class ViewModelBase<T> : INotifyPropertyChanged
{
private static Example.Resources.Cultures.AppResources _uiTexts = new Resources.Cultures.AppResources();

public Example.Resources.Cultures.AppResources UITexts
{
get
{
return _uiTexts;
}
}

public void ChangeLanguage(string language)
{
Example.Resources.Cultures.AppResources.Culture = new System.Globalization.CultureInfo(language);
OnPropertyChanged(„UITexts“);
}

public App Application
{
get
{
return App.Current as App;
}
}

#region INotifyPropertyChanged Implementation
public event PropertyChangedEventHandler PropertyChanged;

protected void NotifyPropertyChanged<TProperty>(
Expression<Func<T, TProperty>> propertyExpression)
{
MemberExpression memberExpression = propertyExpression.Body
as System.Linq.Expressions.MemberExpression;
if (memberExpression == null || (memberExpression != null &&
memberExpression.Member.MemberType != MemberTypes.Property))
{
throw new ArgumentException(
„The specified expression does not represent a valid property“);
}
OnPropertyChanged(memberExpression.Member.Name);
}

protected void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler p = PropertyChanged;
if (p != null)
{
p(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
}
}

Abb.: Ressourcen Handles

Und so einfach ist der Einsatz im XAML:

<TextBlock x:Name=“PageTitle“
Text=“{Binding UITexts.LocationsHeader}“ />

Quelle:

Windows Phone 7 MVVM ViewModel ideas

Frisches Futter für App Designer

Eine neue Episode über Design Fragen ist beim Altmeister John Papa als Video zu finden. Dieses mal zu zum wiederholten Mal: Corrina

 

image

Es geht hauptsächlich um Wireframes und dessen Nutzung für App Developer.

Quellen:

John Papa Blog
Channel9

 

MVVM und deren Übersetzung

Ein Thema das ich auch in meiner App Entwicklung schon mehrfach hatte lautet Mehrsprachigkeit einer App.

Grundsätzlich ist es lösbar, aber einen neuen besseren Ansatz habe ich jetzt bei Joost van Schaik auf seinen Blog gefunden. Er hat einen anderen Ansatz als ich, und ich muss gestehen ich werde umdenken müssen und man sieht wieder, man lernt nie aus.

using System;
using GalaSoft.MvvmLight;

namespace Wp7nl.Globalization
{
  /// <summary>
  /// Supported languages
  /// </summary>
  public class Language : ViewModelBase, IEquatable<Language>
  {
    private string locale;
    public string Locale
    {
      get { return locale; }
      set
      {
        if (locale != value)
        {
          locale = value;
          RaisePropertyChanged(() => Locale);
        }
      }
    }

Quelle:

MVVMLight based language selection for Windows Phone 7

Refactoring MVVM inclusive IoC Part 1

Ich habe schon viele Apps mit MVVM erstellt, Aber auf dem Blog von Kelly Sommers Kellabyte, habe ich einen extrem guten Post gefunden wie man seine MVVM Logik durch Refactoring sinnvoll umbaut und somit eine bessere Logik für seinen MVVM aufsetzt.

Dieser Post besteht aus 3 Teilen:

  • Part 2: ViewModelResolver, composition root and encapsulating the IoC container
  • Part 3: Handling special cases like late registrations outside the composition root
  • Part 4: Unit testing

Before

01 public TViewModel ViewModel
02 {
03     get
04     {
05         TViewModel viewModel;
06         bool wasCreated;
07         bool designMode = DetectDesignMode();
08
09         if (designMode)
10         {
11             viewModel = new TDesignViewModel();
12             wasCreated = true;
13         }
14         else
15         {
16             if (shareInstances)
17             {
18                 viewModel = (TViewModel)sharedInstances.CreateOrGetValue(
19                                 typeof(TViewModel),
20                                 () => new TViewModel(), out wasCreated);
21             }
22             else
23             {
24                 viewModel = new TViewModel();
25                 wasCreated = true;
26             }
27         }
28
29         viewModel.OnLocated(wasCreated);
30         return viewModel;
31     }
32 }

 

After

01 public TViewModel ViewModel
02 {
03     get
04     {
05         TViewModel viewModel;
06         bool designMode = DetectDesignMode();
07
08         if (designMode)
09         {
10             // At design time instantiate design time version.
11             // This populates mock data, dependencies don't have to be real.
12             viewModel = new TDesignViewModel();
13         }
14         else
15         {
16             // Request IoC container to resolve view model & its deps.
17             viewModel =
18                 ApplicationHost.Current.Container.Resolve<TViewModel>();
19         }
20
21         viewModel.OnLocated(wasCreated);
22         return viewModel;
23     }
24 }

 

Quelle:

Refactoring to improve maintainability and blendability using IoC part 1: View Models

Geo Service Bing Service Wrapper

Auf dem  Xaml Ninja Blog ist ein genialer Post erschienen wir der Developer eine Wrapperclass erstellt mit WP7 Contrib. Richtig ins Detail gehts tief in die Entwicklung und saubere Abwicklung von Problemen wie Logging, und MVVM  deren Erstellung.

Aufbau eines ViewModels inclusive Services:

First up we need to declare the private fields so let’s go ahead and do that

01.private readonly IBingMapService bingMapService;
02.private readonly ILocationService locationService;
03.private LocationRect boundingRectangle;
04.private GeoCoordinate currentDeviceGeoCoordinate;
05.private IDisposable currentLocationObserver;
06.private RelayCommand selectFindMyCurrentLocationCommand;
07.private RelayCommand selectFindGeoLocationFromAddressCommand;
08.private Address address;
09.private LocationData locationDataByPoint;
Constuctor des VM:
01.public LocationViewModel(
02.INavigationService navigationService,
03.ILocationService locationService,
04.IBingMapService bingMapService,
05.ILog log)
06.: base(navigationService, log)
07.{
08.this.locationService = locationService;
09.this.bingMapService = bingMapService;
10.this.address = new Address {CountryRegion = "UK", PostalCode = "LE17 5ER"};
11.}
Diese Post ist zu aufwändig das ich ihn in seiner Gesamtheit dastellen kann.
Quelle: