Your Privacy Matters: We use our own and third-party cookies to improve your experience on our website. By continuing to use the website we understand that you accept their use. Cookie Policy
595
Two way binding on WebEditors
posted

I'm using SL3 toolket tab control with the Infragistics WebEditor controls (numeric and mask). 

My set up is the main page has a tab control.  When the app runs it makes a call to a wcf service and returns a list of parent items.  The app then loops the parent items and construct the tabs.  When this happens I have a custom user control will be added to the tab item content.  The user control has a listbox that is set up to display the WebEditor controls by using a DataTemplate.  Within the DataTemplate the WebEditor controls are bonded to a field of the child item using two way binding mode.  When the user control is created one of it's overloaded constructors allows passing in the parent item.  When this happens it makes a call to the wcf service to get the child items then sets data context of the user control.  The list ItemsSource is set to {Binding} making it get its data source from the user control.  This works great, each field is displayed correctly when the application runs but, what I gathered from reading up on two way binding, any changes to the web editor controls don't stick.  After editing the content of one editor control and moving to the next tab and then back the value of the editor is reverted back to the bound value.  I've included a simple configuration that demos this issue.

MainPage.xaml:

<UserControl xmlns:igOB="clr-namespace:Infragistics.Silverlight.Controls;assembly=Infragistics.Silverlight.XamWebOutlookBar.v9.1"  xmlns:igEdit="clr-namespace:Infragistics.Silverlight.Controls;assembly=Infragistics.Silverlight.XamWebEditors.v9.1" 
 xmlns:my="clr-namespace:Microsoft.Expression.Prototyping.Controls;assembly=Microsoft.Expression.Prototyping.Runtime" 
 xmlns:controls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls"
 xmlns:cCustom="clr-namespace:MySilverlightTestApplication" 
 x:Class="MySilverlightTestApplication.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" d:DesignWidth="640" d:DesignHeight="480">
 <Grid x:Name="LayoutRoot">
  <StackPanel Orientation="Horizontal">
     <controls:TabControl x:Name="tabControl"></controls:TabControl>
  </StackPanel>
 </Grid>
</UserControl>

MainPage.cs

namespace MySilverlightTestApplication
{
 public partial class MainPage : UserControl
 {
  ServiceClient client = new ServiceClient();

  public MainPage()
  {
   client.GetGroupsCompleted += new EventHandler<GetGroupsCompletedEventArgs>(client_GetGroupsCompleted);
   Loaded += new RoutedEventHandler(MainPage_Loaded);

   InitializeComponent();

   
  }

  void MainPage_Loaded(object sender, RoutedEventArgs e)
  {
   client.GetGroupsAsync();
  }

  void client_GetGroupsCompleted(object sender, GetGroupsCompletedEventArgs e)
  {
   if (e.Error == null)
   {
    List<TabItem> items = new List<TabItem>();
    foreach (GroupHeader groupHeader in e.Result)
    {
     TabItem tabItem = new TabItem()
     {
      Name = groupHeader.ID.ToString(),
      Header = new TextBlock() { Text = groupHeader.Name },
      Content = new CustomControl(groupHeader)
     };

     tabControl.Items.Add(tabItem);
    }

   }
  }
 }
}

CustomControl.xaml:

 <UserControl xmlns:controlsToolkit="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Toolkit"  xmlns:igEdit="clr-namespace:Infragistics.Silverlight.Controls;assembly=Infragistics.Silverlight.XamWebEditors.v9.1"  x:Class="MySilverlightTestApplication.CustomControl"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Grid x:Name="LayoutRoot" Background="White">
  <StackPanel>
   <TextBlock x:Name="GroupHeaderName"></TextBlock>
   <ListBox x:Name="Container" ItemsSource="{Binding}">
    <ListBox.ItemTemplate>
     <DataTemplate>
      <controlsToolkit:WrapPanel>
       <igEdit:XamWebMaskedEditor x:Name="Phone" Value="{Binding Path=Phone, Mode=TwoWay}" Mask="(999)999-9999"></igEdit:XamWebMaskedEditor>
       <igEdit:XamWebNumericEditor x:Name="Age" Value="{Binding Path=Age, Mode=TwoWay}" Maximum="99" Minimum="0" ></igEdit:XamWebNumericEditor>
      </controlsToolkit:WrapPanel>
     </DataTemplate>
    </ListBox.ItemTemplate>
   </ListBox>
  </StackPanel>
    </Grid>
</UserControl>

CustomControl.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using MySilverlightTestApplication.Service;

namespace MySilverlightTestApplication
{
 public partial class CustomControl : UserControl
 {
  ServiceClient client = new ServiceClient();

  public GroupHeader Group { get; set; }

  public CustomControl()
  {
   InitializeComponent();
  }

  public CustomControl(GroupHeader group)
  {
   Group = group;

   client.GetItemsCompleted += new EventHandler<GetItemsCompletedEventArgs>(client_GetItemsCompleted);
   Loaded += new RoutedEventHandler(CustomControl_Loaded);

   InitializeComponent();
  }

  void CustomControl_Loaded(object sender, RoutedEventArgs e)
  {
   GroupHeaderName.Text = Group.Name;
   client.GetItemsAsync(Group.ID);
  }

  void client_GetItemsCompleted(object sender, GetItemsCompletedEventArgs e)
  {
   if (e.Error == null)
   {
    DataContext = e.Result;
   }
  }
 }
}

WCF Service

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using System.ServiceModel.Activation;

namespace MyServices
{
 // NOTE: If you change the class name "Service" here, you must also update the reference to "Service" in Web.config.
 [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
 [ServiceContract]
 public class Service : IService
 {
  [OperationContract]
  public List<GroupHeader> GetGroups()
  {
   List<GroupHeader> groups = new List<GroupHeader>();
   for (int i = 1; i < 10; i++)
   {
    groups.Add(new GroupHeader() { ID = i, Name = "Group " + i.ToString() });
   }

   return groups;
  }
  
  [OperationContract]
  public List<GroupItem> GetItems(int groupID)
  {
   List<GroupItem> items = new List<GroupItem>();

   for (int i = 0; i < 10; i++)
   {
    if (i == groupID)
    {
     for (int j = 0; j < 15; j++)
     {
      items.Add(new GroupItem()
      {
       ID = j,
       Name = "Group " + i.ToString() + " - Item " + j.ToString(),
       Phone = "1234567890",
       Age = j + i
      });
     }
     break;
    }
   }

   return items;
  }
 }

 [DataContract]
 public class GroupHeader
 {
  [DataMember]
  public int ID { get; set; }
  [DataMember]
  public string Name { get; set; }

  public GroupHeader() { }
 }

 [DataContract]
 public class GroupItem
 {
  [DataMember]
  public int ID { get; set; }
  [DataMember]
  public string Name { get; set; }
  [DataMember]
  public string Phone { get; set; }
  [DataMember]
  public double Age { get; set; }

  public GroupItem() { }
 }
}