Καλώς ορίσατε στο dotNETZone.gr - Σύνδεση | Εγγραφή | Βοήθεια

C# and .NET Tips and Tricks

Quests in programming in .NET
Porting a WPF application to Windows8

That is, our class implements the INotifyPropertyChanged interface and also raises the notification for the “Description” property whenever the Id or the Name properties are changed in order for the Listbox contents (databound to Description) to be refreshed. Our ViewModel for the application is as follows:

 

public class MainWindowViewModel : INotifyPropertyChanged
{
   private List<Client> _clients;
   public List<Client> Clients
   {
      get { return _clients; }
      set { _clients = value; 
         if (PropertyChanged != null) 
             PropertyChanged(this, new PropertyChangedEventArgs("Clients")); }
    }
    private Client _selectedClient;
    public Client SelectedClient
    {
       get { return _selectedClient; }
       set { _selectedClient = value; 
          if (PropertyChanged != null) 
              PropertyChanged(this, new PropertyChangedEventArgs("SelectedClient")); }
     }
     public MainWindowViewModel() {}
     public void Validate() {
        if (SelectedClient != null) {
           if (String.IsNullOrWhiteSpace(SelectedClient.Name))
              MessageBox.Show("Name cannot be empty for client");
           else
              MessageBox.Show("All ok");
        }
     }
     public event PropertyChangedEventHandler PropertyChanged;
}

 

Again, the ViewModel implementes the INotifyPropertyChanged interface and has the Clients property which will be databound to the ItemSource of the Listbox and the SelectedClient property which will be databound to the SelectedItem of the Listbox and to the detail Textboxes at the bottom of the window. Moreover, it provides the Validate method for validating the results. The XAML file describing the UI of the window is as follows:

 

<Window x:Class="AskADev.Article1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Demo WPF porting to Windows8" Height="400" Width="544" Loaded="Window_Loaded">
    <DockPanel>
        <Canvas DockPanel.Dock="Bottom" Height="100" Background="Beige">
            <TextBlock Text="Id" Canvas.Left="6" Canvas.Top="12" />
            <TextBox Text="{Binding SelectedClient.Id}" Canvas.Left="79" 
                                                        Canvas.Top="9" Width="72" />
            <TextBlock Text="Name" Canvas.Left="6" Canvas.Top="40" />
            <TextBox Text="{Binding SelectedClient.Name}" Canvas.Left="79" 
                                                          Canvas.Top="37" Width="311" />
            <Button x:Name="ButtonSubmit" Height="31" Width="73" Canvas.Left="443" 
                   Canvas.Top="63" Click="ButtonSubmit_Click">Validate</Button>
        </Canvas>
        <ListBox DockPanel.Dock="Top" ItemsSource="{Binding Clients}" 
                 SelectedItem="{Binding SelectedClient}" DisplayMemberPath="Description"/>
    </DockPanel>
</Window>

 

Where you can see the data bound properties. Finally the XAML.cs file initializes the ViewModel, attaches it to the DataContext and also provides the event handler for the button:

 

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    ViewModel = new MainWindowViewModel();
    DataContext = ViewModel;
}
private void ButtonSubmit_Click(object sender, RoutedEventArgs e)
{
   ViewModel.Validate();
}
 

We compile this and run it on a Windows7 machine and it runs correctly. Now we start the Windows8 Virtual Machine (instructions on how to install Windows8 on your desktop can be found in this post), get the executable we have created and run it on Windows8 “as is”:

image

Obviously, as expected, the application runs without any problems. But it runs on “Desktop” mode, while we want to make it run on the nice new Metro-Style UI. We open Visual Studio 2011 from within Window8 and select New Project/Templates/Visual C#/Windows Metro Style/Application:

image

The windows in this project template are more “Silverlight” like having as their root content a UserControl and not a Window. Therefore we leave the root declaration intact and copy/paste the inner contents of the original XAML.cs file. The changes we need to make are as follows (all changes are characterized as major/moderate/minor based on the time it will take you to make the changes in a full blown WPF app):

 

  • 1 (moderate) The Window must be converted to UserControl.
  • 2 (major) The “Dockpanel” is not supported (which is kinda expected since we will have a fixed size full screen application) and therefore we change it to a “Canvas” layout.
  • 3 (major) The default mode for the binding in now “One Way”. Therefore we need to specify the binding explicitly to “TwoWay”.
  • 4 (major) Textboxes get enlarged in the new “Metro” style (since they are intended for touch UIs) therefore we need to increase the spacing between the Textboxes (add approximately 10pixels). Of course if we had initially used a Stackpanel for the placement of our controls this would not be needed (good design always handles change more easily Smile)
  • 5 (minor) We need to change the colors to reflect the new style (I chose darker shades)

 

The new XAML is as follows (changes in yellow):

 

<UserControl x:Class="AskADev.Article1.Windows8.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" Loaded="Window_Loaded"
    d:DesignHeight="768" d:DesignWidth="1366">

    <Canvas>
        <Canvas Canvas.Top="668" Width="1366" Height="100">
            <TextBlock Text="Id" Canvas.Left="6" Canvas.Top="12" />
            <TextBox Text="{Binding SelectedClient.Id,Mode=TwoWay}" 
                     Canvas.Left="79" Canvas.Top="9" Width="72" />
            <TextBlock Text="Name" Canvas.Left="6" Canvas.Top="50" />
            <TextBox Text="{Binding SelectedClient.Name,Mode=TwoWay}" 
                     Canvas.Left="79" Canvas.Top="47" Width="311" />
            <Button x:Name="ButtonSubmit" Height="31" Width="73" Canvas.Left="443" 
                    Canvas.Top="63" Click="ButtonSubmit_Click">Validate</Button>
        </Canvas>
        <ListBox Background="Black" Foreground="White" Width="1366" Height="668" 
                 ItemsSource="{Binding Clients}" 
                 SelectedItem="{Binding SelectedClient,Mode=TwoWay}" 
                 DisplayMemberPath="Description"/>
    </Canvas>
</UserControl>
 

The XAML.CS file (apart from some minor changes in the name) remains the same.

Finally, the ViewModel’s file is added as is to the application. The issues that we encounter here are the following:

 

  • 6 (major) The MessageBox is not supported. Therefore you will need to find another way to inform your users about the result (probably from within a special place of the UI). In this app we will just comment it out and do nothing. In real life we would have to change the UI to have a “Messages” area.
  • 7 (minor – but annoying until you discover it) Your application will compile if you leave the INotifyPropertyChanged interface to be defined in the System.ComponentModel assembly as it is for WPF. But the binding will not work! You need to replace the “using System.ComponentModel” statement with “using Windows.Ui.Xaml.Data” which also defines the INotifyPropertyChanged interface and the bindings will magically work!

 

We recompile and run the up and we are in “Metro”!

image

 

Shout it

Share
Posted: Τετάρτη, 19 Οκτωβρίου 2011 6:18 μμ από το μέλος iwannis
Δημοσίευση στην κατηγορία: ,

Σχόλια:

Χωρίς Σχόλια

Ποιά είναι η άποψή σας για την παραπάνω δημοσίευση;

(απαιτούμενο)

(απαιτούμενο)

(προαιρετικό)

(απαιτούμενο)
ÅéóÜãåôå ôïí êùäéêü:
CAPTCHA Image

Ενημέρωση για Σχόλια

Αν θα θέλατε να λαμβάνετε ένα e-mail όταν γίνονται ανανεώσεις στο περιεχόμενο αυτής της δημοσίευσης, παρακαλούμε γίνετε συνδρομητής εδώ

Παραμείνετε ενήμεροι στα τελευταία σχόλια με την χρήση του αγαπημένου σας RSS Aggregator και συνδρομή στη Τροφοδοσία RSS με σχόλια