/// <summary> /// This method saves the record /// </summary> /// <returns></returns> public async System.Threading.Tasks.Task <Entity> Save() { Entity modifiedRecord; // If it is regarding, then pass all the record information which contains mapped data to modifiedrecord. if (isRegarding) { modifiedRecord = Record; } // Otherwise, create blank record else { modifiedRecord = new Entity(); } modifiedRecord.LogicalName = EntityMetadataEx.EntityMetadata.LogicalName; // If update, then assign Id if (isUpdate) { modifiedRecord.Id = Record.Id; } // Only update modified fields foreach (var field in Fields) { // If no data changed, then no need to pass the value. if (isUpdate && field.FieldData == Record[field.FieldMetadata.LogicalName]) { continue; } // If required fields have no value, then show error message. if ((bool)field.FieldMetadata.IsValidForCreate && (field.FieldMetadata.RequiredLevel.Value == AttributeRequiredLevel.ApplicationRequired || field.FieldMetadata.RequiredLevel.Value == AttributeRequiredLevel.SystemRequired) && field.FieldData == null) { MessageDialog dialog = new MessageDialog(string.Format(loader.GetString("RequiredField"), field.FieldMetadata.DisplayName.UserLocalizedLabel.Label)); await dialog.ShowAsync(); lvFields.SelectedItem = ((lvFields.FindName("lbl" + field.FieldMetadata.LogicalName) as TextBlock).Parent as StackPanel).Parent; lvFields.UpdateLayout(); lvFields.ScrollIntoView(lvFields.SelectedItem); return(null); } // If value has been changed, then pass the data to modified record. modifiedRecord[field.FieldMetadata.LogicalName] = field.FieldData; } progressRing.IsActive = true; // Create/Update record. Entity result = await CRMHelper.UpsertRecord(modifiedRecord); // If this is update then retrieve latest data again from server after update and return. if (isUpdate) { ColumnSet columnSet = new ColumnSet(); columnSet.AddColumns(Fields.Select(x => x.FieldMetadata.LogicalName).ToArray()); return(await CRMHelper.RetrieveRecord(EntityMetadataEx.EntityMetadata, result.Id, columnSet)); } // If this is new record, then simply return result. else { return(result); } }
/// <summary> /// Loading data /// </summary> public async System.Threading.Tasks.Task LoadData() { // Get windows width var w = Window.Current.Bounds.Width; // Show ProgressRing progressRing.IsActive = true; // If there is not cache, then retrieve the fields if (Fields == null) { Fields = await CRMHelper.RetrieveFormFields(EntityMetadataEx, RequestFields); } // Store field logical name to ColumnSet ColumnSet cols = new ColumnSet(Fields.Select(x => x.FieldMetadata.LogicalName).ToArray()); // If there is not cache, then retrieve the record if (Record == null) { Record = await CRMHelper.RetrieveRecord(EntityMetadataEx.EntityMetadata, Id, cols); } // Create fields on the form foreach (var field in Fields) { // Instantiate StackPanel which represents a field StackPanel sp = new StackPanel(); // Skip if there is no value returned or if the field is not for read if (!Record.Attributes.Contains(field.FieldMetadata.LogicalName) || !(bool)field.FieldMetadata.IsValidForRead) { continue; } // If it is primray field, then just store it (which will be used in Page Title in this sample) if (field.FieldMetadata.LogicalName == EntityMetadataEx.EntityMetadata.PrimaryNameAttribute) { field.FieldData = Record.Attributes[field.FieldMetadata.LogicalName].ToString(); continue; } // If it is image field, then place it on the top if (field.FieldMetadata.LogicalName == EntityMetadataEx.EntityMetadata.PrimaryImageAttribute) { // Store data field.FieldData = Record.Attributes[field.FieldMetadata.LogicalName]; // Instantiate Image and give same height/width. EntityImageControl imageControl = new EntityImageControl(); imageControl.ImageBytes = field.FieldData as byte[]; // Mark it as ReadOnly imageControl.ReadOnly = true; // Finally add it. sp.Children.Add(imageControl); sp.DataContext = field; // Add imgae to top of the form. this.lvFields.Items.Insert(0, sp); // Image Field doesn't need further processing. continue; } // Skip if it is address field (not email address though) and not composite field, // as Composite contorl data will be displayed on the form instead individual field. if (field.FieldMetadata.GetType().Equals(typeof(StringAttributeMetadata)) && (field.FieldMetadata as StringAttributeMetadata).Format != StringFormat.Email && (field.FieldMetadata.LogicalName.Contains("address") && !field.FieldMetadata.LogicalName.Contains("composite"))) { continue; } // For other fields // Set field name on the left of the field. If you want to set field name // above the data, change folloing to sp.Orientation = Orientation.Vertical; sp.Orientation = Orientation.Horizontal; // Assign data to FieldData field.FieldData = Record.Attributes[field.FieldMetadata.LogicalName]; // Set Field Displayname TextBlock label = new TextBlock(); label.Text = field.FieldMetadata.DisplayName.UserLocalizedLabel.Label + ": "; // Changing stile label.Style = (Style)Application.Current.Resources["BodyTextBlockStyle"]; // Fix the field name width but mark it as Wrap so that long field name can be shown. label.Width = 100; label.TextWrapping = TextWrapping.Wrap; // Finally add it. sp.Children.Add(label); // Set field data. User Formatted Value if available. object value = CRMHelper.GetValue((Record.FormattedValues.Contains(field.FieldMetadata.LogicalName) ? Record.FormattedValues[field.FieldMetadata.LogicalName] : Record.Attributes[field.FieldMetadata.LogicalName])); // If value is string type if (value.GetType() == typeof(string)) { TextBlock fieldValue = new TextBlock(); fieldValue.Text = value.ToString(); fieldValue.Style = (Style)Application.Current.Resources["BodyTextBlockStyle"]; fieldValue.TextWrapping = TextWrapping.Wrap; // Set width. The value is calculated by using field name width and mergin of List. fieldValue.Width = w - 136; sp.Children.Add(fieldValue); } // If value is Array type (which infer this is ActivityParty) else if (value.GetType().IsArray) { // To represent each ActivityParty, create another StackPanel //StackPanel childsp = new StackPanel(); // Loop items in Array foreach (var item in value as Array) { TextBlock fieldValue = new TextBlock(); // Add tap event. When an ActivityParty tapped, it navigates to the record. fieldValue.IsTapEnabled = true; fieldValue.Tapped += ActivityPartyField_Tapped; // Set an ActivityParty to DataContext fieldValue.DataContext = item; fieldValue.Text = ((ActivityParty)item).PartyId.Name; fieldValue.Style = (Style)Application.Current.Resources["BodyTextBlockStyle"]; sp.Children.Add(fieldValue); } //sp.Children.Add(childsp); } // Set field data to DataContext sp.DataContext = field; // Add to form this.lvFields.Items.Add(sp); } // Suppress ProgressRing progressRing.IsActive = false; }