Fetstil Fetstil Kursiv Understrykning linje färgläggning tabellverk Punktlista Nummerlista Vänster Centrerat högerställt Utfyllt Länk Bild htmlmode
  • Forum & Blog
    • Forum - översikt
      • .Net
        • asp.net generellt
        • c#
        • vb.net
        • f#
        • silverlight
        • microsoft surface
        • visual studio .net
      • databaser
        • sql-server
        • databaser
        • access
        • mysql
      • mjukvara klient
        • datorer och komponenter
        • nätverk, lan/wan
        • operativsystem
        • programvaror
        • säkerhet, inställningar
        • windows server
        • allmänt
        • crystal reports
        • exchange/outlook
        • microsoft office
      • mjukvara server
        • active directory
        • biztalk
        • exchange
        • linux
        • sharepoint
        • webbservers
        • sql server
      • appar (win/mobil)
      • programspråk
        • c++
        • delphi
        • java
        • quick basic
        • visual basic
      • scripting
        • asp 3.0
        • flash actionscript
        • html css
        • javascript
        • php
        • regular expresssion
        • xml
      • spel och grafik
        • DirectX
        • Spel och grafik
      • ledning
        • Arkitektur
        • Systemutveckling
        • krav och test
        • projektledning
        • ledningsfrågor
      • vb-sektioner
        • activeX
        • windows api
        • elektronik
        • internet
        • komponenter
        • nätverk
        • operativsystem
      • övriga forum
        • arbete karriär
        • erbjuda uppdrag och tjänster
        • juridiska frågor
        • köp och sälj
        • matematik och fysik
        • intern information
        • skrivklåda
        • webb-operatörer
    • Posta inlägg i forumet
    • Chatta med andra
  • Konto
    • Medlemssida
    • Byta lösenord
    • Bli bonsumedlem
    • iMail
  • Material
    • Tips & tricks
    • Artiklar
    • Programarkiv
  • JOBB
  • Student
    • Studentlicenser
  • KONTAKT
    • Om pellesoft
    • Grundare
    • Kontakta oss
    • Annonsering
    • Partners
    • Felanmälan
  • Logga in

Hem / Artiklar / Titel på artikeln

.NET 3.0 en liten översikt - del 5 (WPF)

Postad 2006-12-13 av Simon Dahlbacka i sektionen ASP.NET, C#, Okategoriserat med 0 Kommentarer | Läst av: 5356, Betyg: 0%

Förord

Microsoft har nyligen släppt version 3.0 av .NET frameworket. Vad innehåller det för nytt och användbart då? Vi ska granska en del av nyheterna i en liten artikelserie. Vi fortsätter att titta på Windows Presentation Foundation (WPF).
Innehåll
  » MainForm.xaml
  » DataModel, View, ViewModel
  » Remote
  » INotifyPropertyChanged
  » MessageCollection
  » Klockan
  » ObscenityPredicate
Relaterade artiklar
  » .NET 3.0 en liten översikt - del 1
  » .NET 3.0 en liten översikt - del 2
  » .NET 3.0 en liten översikt - del 3
  » .NET 3.0 en liten översikt - del 4 (WPF)
  » .NET 3.0 en liten översikt - del 6 (WPF) - sista delen
Vi diskuterade WPF allmänt i förra artikeln och doppade tårna lite grann genom att kolla igenom entrypointen App.xaml samt dess codebehind fil.
Vi fortsätter med med första sidan..


MainForm.xaml


xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="WPF Chat client" Height="300" Width="300"
Source="Connect.xaml" ShowsNavigationUI="False">


Vi låter huvudfönstret vara ett NavigationWindow, som tillhandahåller funktionalitet att navigera runt. Vanligaste ändamål för detta är kanske nån sorts wizard (om du inte vill göra din egna webbläsare då alltså). Men funkar finfint även för våra ändamål. I vanliga fall visas en navigeringslist med back och forward knappar. Dessa har vi inget behov av här så därför gömmer vi dom med hjälp av ShowsNavigationUI="False".

Inte heller här är codebehind filen speciellt upphetsande:

using System;

namespace LemonDesign.Chat.Client {
///
/// Interaction logic for MainForm.xaml
///

public partial class MainForm : System.Windows.Navigation.NavigationWindow {

public MainForm() {
InitializeComponent();
}
}
}



DataModel, View, ViewModel

Ett sätt som rekommenderas av dom som vet är att använda sej av nåt som kallas DataModel, View, ViewModel (alternativt Model, View, ViewModel) Detta liknar lite Model View Controller arkitekturen, men ViewModel är alltså ett lager som så att säga wrappar affärslogik relevant för en viss view på lämpligt sätt. Dan Crevier har skrivit en verklighetsnära artikelserie om just detta. John Gossman skriver om M, V, VM


Remote

Vi gör en klass som enkapsulerar kommunikationen med servern och som vi senare använder för databindning. I brist på bättre namn har jag kallat denna "Remote"

Using statements och variabel deklarationer. Vi vill också att callback beteendet skall vara reentrant och vi sköter trådsynkroniseringen själv.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.ServiceModel;
using System.Windows;
using System.Windows.Input;
using System.Windows.Threading;


using LemonDesign.Chat.Contract;

namespace LemonDesign.Chat.Client.ViewModel {
/// Create a sort of viewmodel of the chat service
///

/// The callback behavior thing is important, otherwise we'll
/// end up with deadlock sooner or later

[CallbackBehavior(ConcurrencyMode = ConcurrencyMode.Reentrant, UseSynchronizationContext = false)]
public class Remote : IChatEvents, INotifyPropertyChanged {
private DuplexChannelFactory m_factory;
private IChat m_server;
private MessageCollection m_messages;
private bool m_isConnected;
private Dispatcher m_dispatcher;


Konstruktor, upprätta kontakt till servern (jo, felhanteringen saknas...) och spara undan ett Dispatcher objekt för trådsynkronisering.

///
/// Create a new instance
///

/// the url to connect to
/// the username
public Remote(string url, string user) {
NetNamedPipeBinding binding = new NetNamedPipeBinding();
m_factory = new DuplexChannelFactory(new InstanceContext(this), binding);
EndpointAddress address = new EndpointAddress(url);
m_server = m_factory.CreateChannel(address);
m_messages = new MessageCollection();
m_server.Connect(user);
IsConnected = true;
/* dispatcher, think Control.Invoke from WinForms land
* used to get things back on the UI thread */
m_dispatcher = Dispatcher.CurrentDispatcher;
}


Egenskaper relevanta för databindning.

///
/// All messages received from server, used in databinding
///

public MessageCollection Messages {
get { return m_messages; }
}

///
/// Indicate connection status
///

public bool IsConnected {
get { return m_isConnected; }
set {
if (value != m_isConnected) {
m_isConnected = value;
OnPropertyChanged("IsConnected");
}
}
}



Kod för kommunikation med servern.

///
/// Send message to server
///

/// the message to send
internal void Send(string message) {
try {
m_server.Say(message);
} catch (FaultException fault) {
MessageBox.Show(fault.Message);
}
}


#region IChatEvents Members
///
/// Server notifies that it is going down
///

public void ServerGoingDown() {
IsConnected = false;
}

///
/// Server received a message
///

/// the message
public void MessageReceived(Message message) {
// ObservableCollection<> et al. only allows
// manipulations from UI thread, so go there...
m_dispatcher.BeginInvoke(DispatcherPriority.Background,
(Action)delegate(Message m) {
m_messages.Insert(0, m);
Debug.Print("Adding {0}", m);
}, message);
}

#endregion



INotifyPropertyChanged

Gränssnittet INotifyPropertyChanged är viktigt, av den anledningen att då fattar WPF att uppdatera databindningen när nåt ändrat. För collections finns INotifyCollectionChanged, fast här är kanske vanligare att direkt använda sej av ObservableCollection<> som vi senare kommer att se.

#region INotifyPropertyChanged Members

public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string property) {
PropertyChangedEventHandler hander = PropertyChanged;
if (hander != null) {
hander(this, new PropertyChangedEventArgs(property));
}
}
#endregion



MessageCollection

MessageCollection är en klass som ärver ObservableCollection<>, och som vi därför kan databinda på ett bra sätt.

using System;
using System.Collections.ObjectModel;

using LemonDesign.Chat.Contract;


namespace LemonDesign.Chat.Client.ViewModel {
///
/// Message collection for data binding purposes
///

public class MessageCollection : ObservableCollection {
}
}


Nu har vi nästan gått igenom hela vår ViewModel förutom två grejer relaterade till:

  • Klockan
  • Datatriggern för fula ord



Klockan

För att vi skall kunna visa meddelandets tidsstämpel som en analog klocka behöver vi en konverterare mellan DateTime och nånting lämpligt. Jag har här valt att konvertera till GeometryDrawing. GeometryDrawing är alltså geometriska figurer som kan användas som "data source" för en bild. En konverterare görs genom att implementera gränssnittet IValueConverter på lämpligt sätt.

using System;
using System.Windows.Data;
using System.Windows.Media;
using System.Windows;
using System.Diagnostics;

namespace LemonDesign.Chat.Client.ViewModel {
[ValueConversion(typeof(DateTime), typeof(GeometryDrawing))]
public class DateTimeToGeometryDrawing : IValueConverter{
#region IValueConverter Members

public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
DateTime timestamp = ((DateTime)value).ToLocalTime();
TimeSpan span = timestamp - DateTime.Today;

GeometryGroup group = new GeometryGroup();
group.Children.Add(new EllipseGeometry(new Rect(-10, -10, 20, 20)));
// hour hand
group.Children.Add(new LineGeometry(new Point(0, 0), new Point(0, -5),
new RotateTransform(span.TotalMinutes / (60 * 12.0) * 360)));
group.Children.Add(new LineGeometry(new Point(0, 0), new Point(0, -10),
new RotateTransform(timestamp.Minute / 60.0 * 360)));

return new GeometryDrawing(Brushes.Transparent, new Pen(Brushes.BlueViolet, 2), group);
}

public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
throw new Exception("The method or operation is not implemented.");
}

#endregion
}
}


Hur vi sedan använder denna konverterare ser vi i nästa artikel.


ObscenityPredicate

Jag har valt att implementera fula ord detektionen på samma sätt med hjälp av en konverterare. I den här konverteraren tar vi parameter objektet i användning för att slippa hårdkoda de fula orden i konverteraren. En annan möjlighet skulle ha varit att använda valideringsregler genom att skriva en egen ValidationRule. Eventuellt gör jag en sådan version i en senare artikel.

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Windows.Data;

namespace LemonDesign.Chat.Client.ViewModel {
[ValueConversion(typeof(string), typeof(bool))]
public class ObscenityPredicate : IValueConverter{
#region IValueConverter Members

public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
string message = value as string;

if (message == null) return false;

message = message.ToLower();
string[] filterWords = ((string)parameter).Split('|');
foreach (string badWord in filterWords) {
foreach (string word in message.Split(' ')) {
if (badWord.ToLower().Trim() == word) {
return true;
}
}
}
return false;
}

public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
throw new Exception("The method or operation is not implemented.");
}

#endregion
}
}


Detta blev en lång artikel. Egentligen är det bara Connect.xaml och ChatPage.xaml som vi har kvar att diskutera. Det gör vi i nästa del av artikelserien.

Som vanligt, frågor och kommentarer mottages tacksamt!
Upp

0 Kommentarer

Skriv en kommentar på artikeln

Ditt betyg på artikeln



Kommentar:





Nyligen

  • 09:09 Vill du köpa medicinska tester?
  • 12:47 Vem beviljar assistansen – kommune
  • 14:17 Någon med erfarenhet av hemstädnin
  • 14:14 Bör man använda sig av en båtförme
  • 14:12 Finns det någon intressant hundblo
  • 14:25 Tips på verktyg för att skapa QR-k
  • 14:23 Tips på verktyg för att skapa QR-k
  • 20:52 Fungerer innskuddsbonuser egentlig

Sidor

  • Hem
  • Bli bonusmedlem
  • Läs artiklar
  • Chatta med andra
  • Sök och erbjud jobb
  • Kontakta oss
  • Studentlicenser
  • Skriv en artikel

Statistik

Antal besökare:
Antal medlemmar:
Antal inlägg:
Online:
På chatten:
4 569 153
27 952
271 704
791
0

Kontakta oss

Frågor runt konsultation, rådgivning, uppdrag, rekrytering, annonsering och övriga ärenden. Ring: 0730-88 22 24 | pelle@pellesoft.se

© 1986-2013 PelleSoft AB. Last Build 4.1.7169.18070 (2019-08-18 10:02:21) 4.0.30319.42000
  • Om
  • Kontakta
  • Regler
  • Cookies