/// <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);
                }
            });
        }
コード例 #6
0
        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);
                }
            });
        }
コード例 #8
0
        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"]);
                    }
                }
            });
        }
コード例 #12
0
        /// <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 });
                }
            });
        }