an dem Projekt wurde nicht mehr weiter gearbeitet. Unter Xp solltest du die auf Windows Forms basierende Version verwenden. Ich hab's (inkl. Quellcode) hier nochmal neu hochgeladen:
...
es läuft, aber es passiert nicht das was soll. Ich habe in der App.xaml die Ressourcen als SolidColorBrushes definiert. Diese haben eine festen Wert. Zur Laufzeit rufe ich dann aktuelle Werte vom Server ab und überschreibe die Ressourcen Application.Current.Ressources["ActiveBackgroundColor"] = newColorBrush . Damit aktualisieren sich in dem Projekt (bzw den Controls) alle Farben automatisch. Damit das mit den Controls des Toolkits (das zweite Projekt) genauso klappt, müssten diese auf die Ressource der Application des ersten Projekts gebunden werden. ResourceDictionary.MergedDictionaries Property hilft mir an der Stelle glaube ich nicht weiter, da die App.xaml ja in einem anderen Projekt liegt. Eigentlich braüchte ich nur den richtigen BindingString, der Projekt bzw Namespace mit berücksichtigt, allerdings weiß ich nicht wie ein solcher aufgebaut ist.
ich habe in meiner Solution 2 Projekte, das erste ist ein Toolkit und das Zweite enthält meine Oberfläche, Logik, etc. In meiner Anwendung lade ich von einem Server extern Farbwerte für die verschiedenen Controls. Nun versuche ich aus meinem Toolkit ein Binding auf eine statische Ressource in meinem anderen Projekt zu erstellen (definiert in App.xaml).
ich hab das Control auf der gleichen Ebene, wie das LayoutGrid "verbaut". Mir ist gerade aufgefallen, dass die VisualStates allerdings erst in dem LayoutGrid definiert werden. Also hab ich es einfach eine Ebene nach unten geschoben und schon lief alles...
Ich bau zur Zeit ein Usercontrol, welches aus einem LayoutRoot(Grid), 2 (custom) Slidern und 2 Buttons besteht. Da sich das Control beim Deaktivieren nicht richtig verhält, hab ich ein DataStateBehavior verbaut, welches auf userControl.IsEnabled binded und die selbst erstellten States Enabled und Disabled ausführt.
eine solche App lässt sich realisieren. Die Übertragung der Daten zwischen PC und WinPhone ist dabei aus meiner Sicht das schwierigste, ein "Explorer" zum direkten Kopieren der Dateien steht nicht (direkt) zur Verfügung. Es gibt im Netz einige Beispiele zum Thema (beliebige) Daten zwischen PC und Phone zu übertragen. Die Übertragung lässt sich aber auf alle Fälle über eine Client-Server-Implementierung lösen.
Die Lösung mit den eigenem WCF Servcie wird vermutlich die Finale werden,
ich werde heute mal die WP7.1 DevTools probieren, vlt ist das Problem damit behoben.
Der Aufruf läuft so:
Login(...)
Beginlogin(...)
EndLogin(...), Hier ist result erst gefüllt, mit dem ((System.ServiceModel.Channels.ServiceChannel.SendAsyncResult)(result)).Rpc.Reply, wo der reply drins teht, dann kommt der Fehler bei base.EndInvoke, innerhalb des try blocks, dann geht er raus und der Reply ist aus result auch nicht mehr zu bekommen.
RemoteClientLoginCompleted(object sender, loginCompletedEventArgs e) wobei e.Error und e.Expression beide Could not evaluate expression haben.
der Fehler tritt genau beim Aufruf von base.EndInvoke("getCubeState", _args, result))); auf. Einfach das EndInvoke nicht aufzurufen, verhindert natürlich den Fehler, allerdings bekomme ich dann trotzdem nicht die ClientException zurück. In dieser stehen allerdings die wichtigen Details, was genau schief gelaufen ist.
//edit
die completed Methode wird aufgerufen, allerdings fliegt der Fehelr schon vorher...
public getCubeStateCompletedEventArgs (object[] results, Exception exception, bool cancelled, object userState) : base(exception, cancelled, userState)
{
this.results = results;
}
public string Result
{
get
{
base.RaiseExceptionIfNecessary();
return ((string)(results[0]));
}
}
dabei sind: results ein array mit einem objeckt vom typ null, exception null, cancelled false, userstate null
ich programmiere zur zeit an einer WindowsPhoneApp, die ein SOAP basierten Webservice nutzt. Den Service spreche ich über einen (aus dem WSDL-File) generierten WCF Client an. Alle Aufrufe erfolgen asyncrone. Leider habe ich Probleme beim Aufruf von EndInvoke (in der Reference.cs), wenn der Service ein Fehler zurück gibt. Theoretisch müsste der Client an der Stelle EndInvoke aufrufen und eine ClientException zurückgeben (ClientException ist in der WSDL beschrieben). Statt dessen kommt der folgende Fehler. Tritt keine fehler auf funktioneirt EndInvoke.
Fehler
base.EndInvoke("getCubeState", _args, result) fails with
InvalidCastException bei System.ServiceModel.Dispatcher.XmlSerializerObjectSerializer.ReadObject(XmlDictionaryReader reader, Boolean verifyObjectName)
bei System.Runtime.Serialization.XmlObjectSerializer.ReadObject(XmlReader reader, Boolean verifyObjectName)
bei System.Runtime.Serialization.XmlObjectSerializer.InternalReadObject(XmlReaderDelegator reader, Boolean verifyObjectName)
bei System.Runtime.Serialization.XmlObjectSerializer.ReadObjectHandleExceptions(XmlReaderDelegator reader, Boolean verifyObjectName)
bei System.Runtime.Serialization.XmlObjectSerializer.ReadObject(XmlDictionaryReader reader)
bei System.ServiceModel.Dispatcher.XmlSerializerFaultFormatter.CreateFaultException(MessageFault messageFault, String action)
bei System.ServiceModel.Dispatcher.FaultFormatter.Deserialize(MessageFault messageFault, String action)
bei System.ServiceModel.Channels.ServiceChannel.HandleReply(ProxyOperationRuntime operation, ProxyRpc& rpc)
bei System.ServiceModel.Channels.ServiceChannel.EndCall(String action, Object[] outs, IAsyncResult result)
bei System.ServiceModel.ClientBase1.ChannelBase1.EndInvoke(String methodName, Object[] args, IAsyncResult result)
bei WindowsPhoneStr.ServiceReferenceSoap.RemoteClient.RemoteClientChannel.EndgetCubeState(IAsyncResult result)
bei WindowsPhoneStr.ServiceReferenceSoap.RemoteClient.WindowsPhoneStr.ServiceReferenceSoap.IRemote.EndgetCubeState(IAsyncResult result)
bei WindowsPhoneStr.ServiceReferenceSoap.RemoteClient.OnEndgetCubeState(IAsyncResult result)
bei System.ServiceModel.ClientBase1.OnAsyncCallCompleted(IAsyncResult result)
bei System.ServiceModel.AsyncResult.Complete(Boolean completedSynchronously)
bei System.ServiceModel.AsyncResult.Complete(Boolean completedSynchronously, Exception exception)
bei System.ServiceModel.Channels.ServiceChannel.SendAsyncResult.CallComplete(Boolean completedSynchronously, Exception exception)
bei System.ServiceModel.Channels.ServiceChannel.SendAsyncResult.FinishSend(IAsyncResult result, Boolean completedSynchronously)
bei System.ServiceModel.Channels.ServiceChannel.SendAsyncResult.SendCallback(IAsyncResult result)
bei System.ServiceModel.AsyncResult.Complete(Boolean completedSynchronously)
bei System.ServiceModel.AsyncResult.Complete(Boolean completedSynchronously, Exception exception)
bei System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelAsyncRequest.OnGetResponse(IAsyncResult result)
bei System.Net.Browser.ClientHttpWebRequest.<>c__DisplayClassa.<InvokeGetResponseCallback>b__8(Object state2)
bei System.Threading.ThreadPool.WorkItem.doWork(Object o)
bei System.Threading.Timer.ring()
Das Problem beschränkt sich scheinbar auf WP7+WCF. Der gleiche Service funktioniert aus einer WPF anwendung einwandfrei.
ich hab heut mal ein etwas anderes Problem...
Ich hab ein SOAP-Webservice (mit wsdl), den ich über eine von VS generierte Klasse anspreche. Die Klasse verwendet WCF. Leider benötige ich für die Kommunikation noch ein zusätzlichen HTTP-Header in jedem Request.
Ich hab versucht das exemplarisch für ein Request zu lösen mit:
public void GetState()
{
using (new System.ServiceModel.OperationContextScope(_remoteClient.InnerChannel))
{
MessageHeader head = MessageHeader.CreateHeader("SessionToken", "", "abc123";);
OperationContext.Current.OutgoingMessageHeaders.Add(head);
_remoteClient.getStateAsync();
}
}
Ich hab inetwa Stück code, was ich oben gepostet habe mit einem Image Control in Silverlight 4 probiert und das Bild wurde angezeigt. Browser ist dabei Chrome gewesen. Ich hab Uri = Absolute genommen vlt wirkt sich das noch aus.
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
namespace SilverlightApplication2
{
public partial class MainPage : UserControl
{
public MainPage()
{
InitializeComponent();
}
private void LayoutRoot_Loaded(object sender, RoutedEventArgs e)
{
Image image = new Image();
Uri uri = new Uri("http://www.einfach-persoenlich.de/photoblog/bilder/netz-auge.jpg", UriKind.Absolute);
ImageSource img = new System.Windows.Media.Imaging.BitmapImage(uri);
image.SetValue(Image.SourceProperty, img);
image1.Source = image.Source;
}
}
}
ich hab ein kleines Schönheitsproblem in meinem Code. Zuerst ein bisschen Code:
[DataContract]
public class User
{
[DataMember]
public string Name { get; set; }
[DataMember]
public int Age { get; set; }
public User() { }
public User(string newName, int newAge)
{
Name = newName;
Age = newAge;
}
}
Das ist bespielhaft meine Datenklasse. Die Properties sind alle groß geschrieben. In meinem Programm bekomm ich allerdings ein JSON Objekt in der Form "{'name':'Bill', 'age':53}" zurück, mit klein geschriebenen Properties. Nun streubt sich der DataContractJsonSerializer den JSON-String in meine Klasse zu konvertieren solange ich die Properties nicht auch kleinschreibe, was wiederrum schrecklich aussieht...
Gibt es eine Lösung ein "IgnoreCase" zu erzwingen? - Das trotz klein geschriebener Properties im JSON-String mein Objekt mit groß geschriebenen Properties arbeiten kann?
Ich hab leider noch nicht mit der Final gearbeitet, erinner mich aber daran,
dass in der Beta direktes (Bilder) laden von dynamisch generierten URIs nicht möglich war.
Du solltest beim Debugen sehen, dass die ImagSource leer bzw fehlerhaft ist. Daher auch das leere Bild.
Teste am Besten mal eine feste URI und schau ob das Bild dann geladen wird. Wenn dies der Fall ist liegt es an dem Problem.
Ich hatte das auch und hab das so gelöst (Workaround - WP7 BETA Code):
//Load BitmapImage
if (myFile.FileExists(filepath + ".jpg";))
{
myStream = myFile.OpenFile(filepath + ".jpg", FileMode.Open);
// Decode the JPEG stream.
WriteableBitmap myBitmap = PictureDecoder.DecodeJpeg(myStream);
myStream.Close();
myStream.Dispose();
MemoryStream ms = new MemoryStream();
BitmapImage bmp = new BitmapImage();
//Convert WriteableBitmap to BitmapImage
myBitmap.SaveJpeg(ms, myBitmap.PixelWidth, myBitmap.PixelHeight, 0, 100);
bmp.SetSource(ms);
this.addToImages(bmp));
}
else
{...}
die Lösung funktioniert relativ gut, die meisten überflüßigen Datenanfragen kann ich so verhindern. Es kommt vor, dass die Eingabe und Abfrage gleichzeitig auftreten und somit die Abfrage trotzdem durchgeführt wird, aber das ist ehr die Ausnahme.
Hallo gfoidl,
danke für deinen umfangreichen Lösungsansatz. Die OneWay Version hört sich in meinen Ohren nach einer guten Idee an. Ich werde mein Service jetzt umschreiben und dann berichten, ob das Problem damit wirklich gelöst wurde.
Grüße Mazo
P.S: In deinem Beispiel Projekt hast du komische Assemblys eingebunden (nuint.framewrok, moq), der Code ist trotzdem hilfreich ;-)
das mit den Sessions nehm ich mir mal vor und werde es ausprobieren [morgen :D].
IChannel Abort hab ich schon getestet. Es entsteht das gleiche Problem ich "brech" damit den Channel ab ("immediately from its current state into the closed state") und muss ihn neu aufmachen um ihn wiederzuverwenden.
der WCF Service wird asynchron ausgeführt. Er kann auch mehrere Anfragen parallel verarbeiten. Mir geht es drum, das Senden der Antwort an den Client zu verhindern, wenn dieser schon eine neue Anfrage gestellt hat.
Hallo,
ich hab ein Service der auf Nutzereingaben antworten liefert. Es kommt vor, dass der Nutzer schneller ist als der Service. Nun will ich den Service irgendwie mitteilen,dass er die vorherige Anfrage abbrechen soll und die neue Anfrage bearbeiten.
Gibt es da eine vorgefertigte Lösung ( in WCF integriert) oder muss man sich selbst darum kümmern?
ich versuche mich zur Zeit an einem WCF Service der auf eine Datenbank zurück greift.
Ich hab folgendes Interface erstellt:
[ServiceContract]
public interface IServiceData
{
[OperationContract]
bool SaveContact(string Name, string FirstName, string Number);
[OperationContract]
List<Contact> GetContacts();
}
[DataContract]
public class ContactDataBase : DataContext
{
public Table<Contact> Contacts;
public ContactDataBase(string connstr) : base(connstr)
{
}
}
[DataContract]
[Table(Name = "Contacts";)]
public class Contact
{
[DataMember]
[Column(IsPrimaryKey = true, Storage = "Name";)]
public string Name { get; set; }
[DataMember]
[Column(Storage = "FirstName";)]
public string FirstName { get; set; }
[DataMember]
[Column(Storage = "Number";)]
public string Number { get; set; }
//public BitmapImage Pic { get; set; }
public Contact()
{
this.Name = "";
this.FirstName = "";
this.Number = "";
// this.Pic = null;
}
public Contact(string Name, string FirstName, string Number)
{
this.Name = Name;
this.FirstName = FirstName;
this.Number = Number;
// this.Pic = null;
}
Meine MSSQL Datenbank hat eine Tabele "Contacts" und die Spalten "Name" (nchar(20), primarykey) [mir ist klar, dass der name kein guter pkey ist], "FirstName" (nchar(20)), "Number" (nchar(30)).
Beim Aufruf von ContactDataBase(...) bekomm ich nun den Fehler "Fehlerhafte Storage-Eigenschaft: "Name" im Element "Namespace.Contact.Name"."
Zum testen des Services nutze ich den WCF Test Client.
Kann mir jemand sagen, was ich falsch gemacht habe?