/// <summary> /// Delete selected Keys /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void ToolButtonDelete_Click(object sender, EventArgs e) { // get the selected item from the list var items = ListViewKeyList.SelectedItems; var approveMessage = new StringBuilder(); var keys = new List <EntityKeyMetadata>(); foreach (ListViewItem item in items) { var key = item.Tag as EntityKeyMetadata; var keyName = CrmActions.GetLocalizedLabel(key.DisplayName, key.SchemaName); keys.Add(key); approveMessage.AppendLine($"\t{keyName}"); } var message = $"Are you sure you would like to delete Alternate Key(s)?\n{approveMessage.ToString()}?" + $"\nNOTE: This cannot be undone!"; if (MessageBox.Show(this, message, "Confirm Delete", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) { CrmActions.DeleteEntityKey(Service, keys); LoadSelectedEntityKeys(); } }
/// <summary> /// Save the new key! /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void ButtonSaveNew_Click(object sender, EventArgs e) { ValidateNewKeyInputs(false); if (!AllowSaveNewKey()) { return; } if (MessageBox.Show(this, "Create new Alternate Key?", "Confirm Create", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) { var ent = EntityDropDown.SelectedEntity; var attributes = new List <string>(); // grab the list of schema names from the list box foreach (var item in listBoxAttrbutes.SelectedItems) { attributes.Add(item.ToString().ToLower()); } var newName = $"{comboBoxPrefixes.SelectedItem}_{textNewKeyName.Text}"; var errors = CrmActions.CreateEntityKey(Service, ent.LogicalName, newName, textNewKeyDisplayName.Text, attributes); if (errors != null) { MessageBox.Show(this, errors, "Error Creating Key", MessageBoxButtons.OK, MessageBoxIcon.Error); } ToggleNewKeyPane(false); ToggleNewKeyPaneEnabled(false, true); LoadSelectedEntityKeys(); } }
/// <summary> /// Batch update those failed keys! /// </summary> /// <param name="keys"></param> private void ReactivateKeys(List <EntityKeyMetadata> keys) { WorkAsync(new WorkAsyncInfo { Message = "Reactivating Entity Keys", AsyncArgument = keys, IsCancelable = true, MessageWidth = 340, MessageHeight = 150, Work = (w, e) => { w.ReportProgress(0, $"Reactivating Entity Keys"); var results = CrmActions.ReactivateEntityKey(Service, keys); w.ReportProgress(100, $"Reactivating Entity Keys complete!"); e.Result = results; }, ProgressChanged = e => { SendMessageToStatusBar?.Invoke(this, new StatusBarMessageEventArgs(e.ProgressPercentage, e.UserState.ToString())); }, PostWorkCallBack = e => { // reload the list of selected entities if (e.Result != null) { var errors = (List <string>)e.Result; MessageBox.Show(this, $"The following errors occurred while attempting to activate\n{string.Join("\n", errors)}"); } // reload the list now that have made the call LoadSelectedEntityKeys(); } }); }
/// <summary> /// Activate the FAILED Alternate Keys /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void ToolButtonActivate_Click(object sender, EventArgs e) { // get the selected item from the list var items = ListViewKeyList.SelectedItems; var failedKeys = new List <EntityKeyMetadata>(); var approveMessage = new StringBuilder(); foreach (ListViewItem item in items) { var key = item.Tag as EntityKeyMetadata; if (key.EntityKeyIndexStatus == EntityKeyIndexStatus.Failed) { var keyName = CrmActions.GetLocalizedLabel(key.DisplayName, key.SchemaName); failedKeys.Add(key); approveMessage.AppendLine($"{keyName}"); } } if (failedKeys.Count == 0) { MessageBox.Show(this, $"No Failed Keys Selected. Activate is only supported for Failed Entity Keys", "No Failed Keys Selected", MessageBoxButtons.OK); } else { if (MessageBox.Show(this, $"Activate the following keys?\n{approveMessage.ToString()}", "Reactivate Key?", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) { ReactivateKeys(failedKeys); } } }
/// <summary> /// Retrieve the Attribute metadata for the given EntityLogicalName /// </summary> /// <param name="entityLogicalName"></param> private void RetrieveEntityAttributes(string entityLogicalName) { // lock thing down ToggleNewKeyPaneEnabled(false); WorkAsync(new WorkAsyncInfo { Message = "Retriveing Entity Attributes", AsyncArgument = entityLogicalName, IsCancelable = true, MessageWidth = 340, MessageHeight = 150, Work = (w, e) => { var entLogicalName = e.Argument as string; w.ReportProgress(0, $"Retriveing Entity Attributes"); var results = CrmActions.RetrieveEntity(Service, entLogicalName, true); w.ReportProgress(100, $"Retriveing Entity Attributes complete!"); e.Result = results; }, ProgressChanged = e => { SendMessageToStatusBar?.Invoke(this, new StatusBarMessageEventArgs(e.ProgressPercentage, e.UserState.ToString())); }, PostWorkCallBack = e => { var entity = e.Result as EntityMetadata; PopulateEntityAttributes(entity); } }); }
private void EntitiesListControl_SelectedItemChanged(object sender, EventArgs e) { var ent = EntityListControl.SelectedEntity; UpdateControlLogger(textEntListLog, $"SelectedItemChanged: {ent?.SchemaName}"); if (ent != null) { ent = CrmActions.RetrieveEntity(Service, ent.LogicalName, true, new List <EntityFilters>() { EntityFilters.All }); } SetPropertySelectedObject(radioEntListShowProps, propGridEntList, EntityListControl, ent); }
/// <summary> /// Load the Alternate Key info for the selected Entitie /// </summary> private void LoadSelectedEntityKeys() { ToggleMainUIControlsEnabled(false); var selectedEntities = EntitiesListControl.CheckedEntities; WorkAsync(new WorkAsyncInfo { Message = "Retrieving the list of Entities", AsyncArgument = selectedEntities, IsCancelable = true, MessageWidth = 340, MessageHeight = 150, Work = (w, e) => { var entExpanded = new List <EntityMetadata>(); // then reload details for each var count = 0; var total = selectedEntities.Count; // build the list of keys that we want to retrieve var entLogicalNameList = new List <string>(); foreach (var ent in selectedEntities) { w.ReportProgress(100 * count++ / total, $"Loading Entities: {ent.LogicalName}"); entLogicalNameList.Add(ent.LogicalName); } entExpanded = CrmActions.RetrieveEntity(Service, entLogicalNameList); e.Result = entExpanded; w.ReportProgress(100, $"Loading Entities complete"); }, ProgressChanged = e => { SendMessageToStatusBar?.Invoke(this, new StatusBarMessageEventArgs(e.ProgressPercentage, e.UserState.ToString())); }, PostWorkCallBack = e => { _expandedEntities.Clear(); _expandedEntities = e.Result as List <EntityMetadata>; // now load up the list view with the keys PopulateKeysListView(); ToggleMainUIControlsEnabled(true); } }); }
private void LoadEntities() { WorkAsync(new WorkAsyncInfo { Message = "Retrieving the list of Entities", AsyncArgument = propertyGridConfig.SelectedObject, IsCancelable = true, MessageWidth = 340, MessageHeight = 150, Work = (w, e) => { try { w.ReportProgress(0, "Loading Entities from CRM"); var config = e.Argument as ConfigurationInfo; e.Result = CrmActions.GetAllEntities(Service, config); w.ReportProgress(100, "Loading Entities from CRM Complete!"); } catch (Exception ex) { MessageBox.Show("An error occured attetmpting to load the list of Entities:\n" + ex.Message); } }, ProgressChanged = e => { SendMessageToStatusBar?.Invoke(this, new StatusBarMessageEventArgs(e.ProgressPercentage, e.UserState.ToString())); }, PostWorkCallBack = e => { // let them do stuff again ToggleMainControlsEnabled(true); SendMessageToStatusBar?.Invoke(this, new StatusBarMessageEventArgs(0, "")); // launch the results window... get off this worker thread so we can work with the dialog correctly BeginInvoke(new LoadEntitiesCompleteDelegate(LoadEntitiesComplete), new object[] { e.Result as List <EntityMetadata> }); } }); }
/// <summary> /// Load the list of attributes that are allowed to be included as keys /// </summary> /// <param name="entity"></param> private void PopulateEntityAttributes(EntityMetadata entity) { // save the entity reference so we can do some validation. listBoxAttrbutes.Tag = entity; listBoxAttrbutes.Items.Clear(); listBoxAttrbutes.DisplayMember = "Name"; var attributes = entity.Attributes.ToList(); if (attributes != null) { // only allowed certain types: // https://docs.microsoft.com/en-us/dynamics365/customer-engagement/developer/define-alternate-keys-entity var allowed = attributes.Where(a => (a is DecimalAttributeMetadata) || (a is IntegerAttributeMetadata) || (a is StringAttributeMetadata) // || (a is DateTimeAttributeMetadata) // these will be available in v9.1 // || (a is LookupAttributeMetadata) // ||(a is PicklistAttributeMetadata) ); // add the items to the checked list foreach (var attrib in allowed) { if ((attrib.AttributeOf == null) && (attrib.AttributeType != AttributeTypeCode.Virtual)) { listBoxAttrbutes.Items.Add(new AttributeListItem() { Name = $"{CrmActions.GetLocalizedLabel(attrib.DisplayName, attrib.SchemaName)} ({attrib.SchemaName})", SchemaName = attrib.SchemaName }); } } } // reenable ToggleNewKeyPaneEnabled(true); ValidateNewKeyInputs(true); }
/// <summary> /// Populate the Key Details pane controls with the Key Info /// </summary> /// <param name="key"></param> private void UpdateKeyDetailsPane(EntityKeyMetadata key) { labelKeyLogicalNameValue.Text = null; labelKeyIsManagedValue.Text = null; labelKeyMetadataIdValue.Text = null; labelKeySchemaNameValue.Text = null; labelKeyNameValue.Text = null; labelKeyStatusValue.Text = null; labelScheduledJobValue.Text = null; if (key != null) { labelKeyNameValue.Text = CrmActions.GetLocalizedLabel(key.DisplayName, key.SchemaName); labelKeyLogicalNameValue.Text = key.LogicalName; labelKeySchemaNameValue.Text = key.SchemaName; labelKeyStatusValue.Text = key.EntityKeyIndexStatus.ToString(); labelKeyIsManagedValue.Text = key.IsManaged.Value.ToString(); labelKeyMetadataIdValue.Text = key.MetadataId.Value.ToString("b"); labelScheduledJobValue.Text = (key.AsyncJob != null) ? ((EntityReference)key.AsyncJob).Name : null; } }
/// <summary> /// Populate the Alternate Key details pane /// </summary> private void PopulateNewKeyControls() { ToggleNewKeyPaneEnabled(false); ToggleMainUIControlsEnabled(false); // load the entities into the drop down control EntityDropDown.LoadData(); WorkAsync(new WorkAsyncInfo { Message = "Retrieving Publishers", AsyncArgument = null, IsCancelable = true, MessageWidth = 340, MessageHeight = 150, Work = (w, e) => { var entLogicalName = e.Argument as string; w.ReportProgress(0, $"Retrieving Publishers"); var results = CrmActions.RetrievePublishers(Service); w.ReportProgress(100, $"Retrieving Publishers complete!"); e.Result = results; }, ProgressChanged = e => { SendMessageToStatusBar?.Invoke(this, new StatusBarMessageEventArgs(e.ProgressPercentage, e.UserState.ToString())); }, PostWorkCallBack = e => { var pubs = e.Result as List <Entity>; comboBoxPrefixes.Items.Clear(); // load the publishers foreach (var pub in pubs) { comboBoxPrefixes.Items.Add(pub.Attributes["customizationprefix"]); } } }); }
/// <summary> /// Based on the current selection, generate the templates /// </summary> /// <param name="generateCheckedItems">Flag indicating whether to generate the checked items or the single selected item</param> private void GenerateTemplates(bool generateCheckedItems = false) { ToggleMainControlsEnabled(false); var entitiesList = new List <string>(); // generate checked vs selected items. if (generateCheckedItems) { foreach (ListViewItem item in listViewEntities.CheckedItems) { entitiesList.Add(item.SubItems["Name"].Text); } } else { var selItem = listViewEntities.SelectedItems[0]; entitiesList.Add(selItem.SubItems["Name"].Text); } WorkAsync(new WorkAsyncInfo { Message = "Generating the script template for selected entities", AsyncArgument = new List <object>() { entitiesList, propertyGridConfig.SelectedObject }, IsCancelable = true, MessageWidth = 340, MessageHeight = 150, Work = (w, e) => { Xrm2TypeScriptGenerator xrm2ts = null; try { var args = e.Argument as List <object>; var namesList = args[0] as List <string>; var config = args[1] as ConfigurationInfo; // collect all of the entity metadata items with the attribubte metadata var selectedEntities = new List <EntityMetadata>(); var counter = 0; var total = namesList.Count; //foreach selected entity in the listbox foreach (string logicalName in namesList) { w.ReportProgress((counter++ / total) * 100, "Loading Entity: " + logicalName); selectedEntities.Add(CrmActions.RetrieveEntityAttributeMeta(Service, config, logicalName)); } w.ReportProgress(100, "Loading Entities Complete"); // generate the list of selected entities xrm2ts = new Xrm2TypeScriptGenerator(config, selectedEntities); // TODO move the type into the script types xrm2ts.GenerateAllClassTemplates(); e.Result = xrm2ts; } catch (Exception ex) { MessageBox.Show("An error occurred attempting to generate the template for your selection:\n" + ex.Message + "\n Logging results:\n" + xrm2ts.Logger.ToString()); } }, ProgressChanged = e => { SendMessageToStatusBar?.Invoke(this, new StatusBarMessageEventArgs(e.ProgressPercentage, e.UserState.ToString())); }, PostWorkCallBack = e => { // let them do stuff again ToggleMainControlsEnabled(true); // launch the results window... get off this worker thread so we can work with the dialog correctly BeginInvoke(new ProcessingCompleteDelegate(ProcessingComplete), new object[] { e.Result as Xrm2TypeScriptGenerator }); } }); }