| Bernhard's profileBernhard Grojer - BlogPhotosBlogLists | Help |
|
|
April 09 Silverlight: DataBinding zu WCF Service - Teil 2/2
Dictionary<Customer, string> _ChangedObjects = new Dictionary<Customer, string>();
public void RegisterChangeTracking(Customer c)
{
c.PropertyChanged += (sender, e) =>
{
var cus = sender as Customer;
if (_ChangedObjects.ContainsKey(cus))
_ChangedObjects[cus] += ";" + e.PropertyName;
else
_ChangedObjects.Add(cus, e.PropertyName);
};
}Bevor nun ein Objekt in die Observable<T> Liste wandert (und somit im UI dargestellt wird) wird es mithilfe von RegisterChangeTracking T o) registriert. private void LoadCustomers()
{
CustomerServiceClient client = new CustomerServiceClient();
client.GetCustomersCompleted += (sender, e) =>
{
foreach (var c in e.Result)
{
_Customers.Add(c);
RegisterChangeTracking(c);
}
};
client.GetCustomersAsync();
}Nun müssen wir nur noch das Dictionary mit den geänderten Daten dem WCF Service übergeben. private void SaveCustomers()
{
CustomerServiceClient client = new CustomerServiceClient();
client.SaveCustomersCompleted += (sender, e) =>
{
var b = e.Result;
};
client.SaveCustomersAsync(_ChangedObjects);
}
Die Methode SaveCustomer wird nun aus der Silverlight-Anwendung aufgerufen (ein Button im UI triggert folgenden Code): private CustomerDataSource CustomerDataSource
{
get
{
return this.Resources["Customers"] as CustomerDataSource;
}
}
private void ButtonSave_Click(object sender, RoutedEventArgs e)
{
CustomerDataSource.Save();
}
public bool SaveCustomers(Dictionary<Customer, string> Customers)
{
using (var DB = new NorthwindDataContext())
{
var query = from c in DB.Customers
where Customers.Keys.Select(cus => cus.CustomerID).Contains(c.CustomerID)
select c;
var lst = query.ToList();
Type t = typeof(Customer);
foreach (var kv in Customers)
{
var oldCustomer = kv.Key;
var newCustomer = lst.Single(cus => cus.CustomerID == oldCustomer.CustomerID);
foreach (var s in kv.Value.Split(new char[] {';'}, StringSplitOptions.RemoveEmptyEntries))
{
var propInfo = t.GetProperty(s);
var v = propInfo.GetValue(oldCustomer, null);
propInfo.SetValue(newCustomer, v,null);
}
}
DB.SubmitChanges();
}
return true;
}Das fertige Beispiel (selber Link wie im Teil 1 d. Blog-Serie) steht zum Download bereit: SilverlightConsumeWCF 08042009.zip April 08 Silverlight: DataBinding zu WCF Service - Teil 1/2
[ServiceContract]
public interface ICustomerService
{
[OperationContract]
List<Customer> GetCustomers();
[OperationContract]
bool SaveCustomers(Dictionary<Customer, string> Customers);
}
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class CustomerService : ICustomerService
{
#region ICustomerService Members
public List<Customer> GetCustomers()
{
using (var DB = new NorthwindDataContext())
{
var query = from c in DB.Customers
select c;
return query.ToList();
}
}
public bool SaveCustomers(Dictionary<Customer, string> Customers)
{
TODO: Implement Save
return true;
}
#endregion
}Damit dieses Service verfügbar ist muss noch die passende web.config (Service Configuration Editor) erstellt werden (passende .svc Datei nicht vergessen bei WCF Service unter WAS/IIS) Damit die Daten aber tatsächlich nachgeladen werden können brauchen wir zuerst einen Proxy den wir über “Add Service Reference” erzeugen lassen. (Meta-Daten müssen vom Service aktiviert/bereitgestellt werden). Sobald der CustomerServiceCleint (generierter Code) nun verfügbar ist können wir eine passende Klasse erzeugen und das Service benutzen. public class CustomerDataSource
{
public CustomerDataSource()
{
LoadCustomers();
}
private void LoadCustomers()
{
CustomerServiceClient client = new CustomerServiceClient();
client.GetCustomersCompleted += (sender, e) =>
{
foreach (var c in e.Result)
{
_Customers.Add(c);
}
};
client.GetCustomersAsync();
}
ObservableCollection<Customer> _Customers = new ObservableCollection<Customer>();
public ObservableCollection<Customer> Customers
{
get {
return _Customers;
}
}
}
<UserControl xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data" x:Class="SilverlightConsumeWCF.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:SilverlightConsumeWCF">
<UserControl.Resources>
<local:CustomerDataSource x:Key="Customers" />
</UserControl.Resources>
<Grid x:Name="LayoutRoot" Background="White">
<data:DataGrid ItemsSource="{Binding Path=Customers, Source={StaticResource Customers}}">
</data:DataGrid>
</Grid>
</UserControl>Download: SilverlightConsumeWCF 08042009.zip Im Teil 2 wird noch editieren der Customer-Objekte ermöglicht. Das Service stellt die entsprechende Methodensignatur bereits bereit. April 07 Silverlight 3: NetworkChange (u. DataBinding mit INotifyPropertyChanged)In Silverlight 3 gibt es nun eine einfache Möglichkeit um den aktuellen Netzwerkstatus zu erkennen. DataBinding: public class NetworkState : INotifyPropertyChanged
{
public NetworkState()
{
NetworkChange.NetworkAddressChanged +=
(sender, args) => SendNotifyPropertyChanged("IsOnline");
}
public void SendNotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
public bool IsOnline
{
get
{
return NetworkInterface.GetIsNetworkAvailable(); ;
}
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
#endregion
}UserControl (XAML): <UserControl x:Class="SilverlightNetworkState.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:SilverlightNetworkState"
Width="400" Height="300">
<UserControl.Resources>
<local:NetworkState x:Key="State" />
</UserControl.Resources>
<Grid x:Name="LayoutRoot" Background="White">
<CheckBox Margin="10" IsChecked="{Binding Path=IsOnline, Source={StaticResource State}}" Content="Online" />
</Grid>
</UserControl>Download: SilverlightNetworkState 07042009.zip |
|
|