Leveraging out-of-box UI components

In extending mobile application, you may need to build additional pages during the implementation of your custom extension or task. The application framework provides out-of-box components that you can leverage to minimize development efforts. These components are also used extensively by the out-of-box application itself, meaning that your extensions will have the similar look and feel and user experience as the application.

If you need to show attributes for a feature, or allow your user to edit attributes, it is recommended that you use the built-in ViewAttributesPage or EditAttributesDialog. Please click here for more details on how to use each of these.

If you intend to build other pages that incorporate tabular information that you want to show your user, or allow the user to modify, there is a set of out-of-box groups that you can use. The concept of group is widely used within the application when it presents information to your user or collects information from your user. A group is essentially a collection of UI controls being grouped together. You should create a GroupView, add it to your page, then add different groups to the GroupView.

The screen capture below shows a ReadOnlyAttributeGroup in ViewAttributesPage. It includes a text BLDGS_ from column name, a value of 11661, and is surrounded by a border.

This is required

The following sample code demonstrates how to add different types of groups to a page and allows your user to edit each of them. For details, please refer to the SimpleDataEntryTask sample.

    private void CreateGroups()
    {
      // Create GroupView
      GroupView gv = new GroupView();
      ReadOnlyAttributeGroup employeeIDGroup = new ReadOnlyAttributeGroup("Employee ID", "351024");
      gv.Groups.Add(employeeIDGroup);
 
      // Department
      string[] departments = new string[] { "Human Resource", "Software Development", "Software Products", "Facilities", "System", "Sales", "Marketing"};
      SelectionGroup<string> departmentGroup = new SelectionGroup<string>("Department", "Software Development", departments, "Software Development", "Software Development");
      gv.Groups.Add(departmentGroup); 

      // Photo
      Group pictureGroup = new Group();
      PictureItem picGroupItem = new PictureItem();
      picGroupItem.Bitmap = (Bitmap)Resources.User;
      pictureGroup.Items.Add(picGroupItem);
      gv.Groups.Add(pictureGroup); 

      // First Name
      StringAttributeGroup firstNameGroup = new StringAttributeGroup("First Name", "Richard", true, 30);
      gv.Groups.Add(firstNameGroup); 

      // Last Name
      StringAttributeGroup lastNameGroup = new StringAttributeGroup("Last Name", "Harris", true, 30);
      gv.Groups.Add(lastNameGroup); 

      // Date of Birth
      DateAttributeGroup dobGroup = new DateAttributeGroup("Date of Birth", DateTime.Now);
      gv.Groups.Add(dobGroup); 

      // Gender
      RadioGroup genderGroup = new RadioGroup("Gender", new string[] { "Male", "Female" });
      genderGroup.CheckedItem = "Male";
      gv.Groups.Add(genderGroup);

       // Distance from work
      DistanceGroup distanceGroup = new DistanceGroup("Distance from work", 5.25, ESRI.ArcGIS.Mobile.SpatialReferences.Unit.Mile);
      gv.Groups.Add(distanceGroup); 

      // Phone Number
      StringAttributeGroup phoneGroup = new StringAttributeGroup("Phone", "(909) 793-2853", false);
      gv.Groups.Add(phoneGroup);

       // Email
      StringAttributeGroup emailGroup = new StringAttributeGroup("E-mail", "support@esri.com", true);
      gv.Groups.Add(emailGroup); 

      this.Controls.Add(gv);
      gv.Dock = DockStyle.Fill; 
      this.Controls.SetChildIndex(gv, 0);
    }

As demonstrated, you can use different types of out-of-box groups as provided by the application framework. If, however, you have additional requirements, you can also build your own group that implements different UI and functionalities to fit your needs.

The following code demonstrates how to create your own group items to deal with blob fields that store audio information. Note that it assumes the audio column name starts with audio_.

    ViewAttributesPage.CreatingViewGroups += new EventHandler<CreatingViewGroupsEventArgs>(ViewAttributesPage_CreatingViewGroups);

    private void ViewAttributesPage_CreatingViewGroups(object sender, CreatingViewGroupsEventArgs e)
    {
      FeatureDataReader reader = e.Feature.GetDataReader();
      try
      {
        reader.ReadFirst();
        foreach (DataColumn dc in reader.FeatureLayer.Columns)
        {
          if (dc.DataType == typeof(byte[]) && dc.ColumnName.ToLower().IndexOf("audio_") == 0)
          {
            FeatureColumnGroup group = new FeatureColumnGroup(e.Feature, dc); 
            TextItem headerItem = new TextItem(dc.ColumnName);
            headerItem.Selectable = false;
            headerItem.Style = TextItemStyle.Bold;
            group.Items.Add(headerItem); 

            bool hasAudio = false;
            if (reader[dc.ColumnName] != DBNull.Value)
            {
              byte[] bytes = (byte[])reader[dc.ColumnName];
              if (bytes != null && bytes.Length > 0)
              {
                LinkItem lgi = new LinkItem("Play Audio");
                lgi.Selectable = true;
                lgi.Activated += new EventHandler(ViewPagePlayAudioLinkActivated);
                group.Items.Add(lgi);
                hasAudio = true;
              }
            } 

            if (!hasAudio)
            {
              TextItem tgi = new TextItem("<No Audio Recorded>");
              tgi.Selectable = false;
              group.Items.Add(tgi);
            } 

            e.Groups.Add(group);
          }
        }
      }
      finally
      {
        if (reader != null)
        {
          // close the reader
          reader.Close();
          reader.Dispose();
          reader = null;
        }
      }
    } 

  public class FeatureColumnGroup : Group
  {
    private DataColumn m_dc;
    private Feature m_feature; 

    public FeatureColumnGroup(Feature feature, DataColumn dc)
      : base()
    {
      m_dc = dc;
      m_feature = feature;
    } 

    public DataColumn DataColumn
    {
      get { return m_dc; }
    } 

    public Feature Feature
    {
      get { return m_feature; }
    }
  }


9/20/2011