CRM 2011-如何根据属性值设置默认表单(不使用Javascript)? [英] Crm 2011 - How to set a default form depending on attribute value (without using Javascript)?

查看:47
本文介绍了CRM 2011-如何根据属性值设置默认表单(不使用Javascript)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个让我发疯的要求:
我们有8种不同的联系实体形式。
我们还有一个包含8个选项的选择列表。
的想法是,基于所选的选项,我们可以打开该联系人记录,默认情况下显示一个特定的表单而无需使用JAVASCRIPT,以避免出现性能问题(每个记录必须加载两次)。示例:

I have a little requirement that is making me crazy: We have 8 different forms for the Contact Entity. We also have a pick list with 8 options. The idea is that based on the option selected we could open that Contact record showing by default a particular form WITHOUT USING JAVASCRIPT in order to avoid performance problems (each record has to be loaded twice). Example:

表格:

表格1

表格2

表格3

Forms:
Form 1
Form 2
Form 3

选择列表值-默认格式:

Pick List Values - Default Form:

表格1

表格2

表格3

Form 1
Form 2
Form 3

如果选择了表格3(选择列表值),则下次我打开该记录时,默认情况下应显示表格3。

If Form 3(pick list value) is selected then, the next time I open that record, Form 3 should be displayed by default.

如果选择了Form 1(选择列表值),则下次我打开该记录时,默认情况下应显示Form 1。

If Form 1(pick list value) is selected then, the next time I open that record, Form 1 should be displayed by default.

我已经在RetrieveFilteredForms消息中的systemform实体处注册了一个插件,更新了userentityuisettings表,并且我能够设置每次打开记录时都会显示的 DEFAULT,无论最后打开的表单是什么

I've trayed registering a plugin at the systemform entity, in RetrieveFilteredForms message, updating the userentityuisettings table and I've been able to set a "DEFAULT" that is displayed every time the records is opened regardless the last opened form.

我已经在联系人实体中注册了一个插件,在检索消息中,更新了userentityuisettings表,但是我发现Crm仅查询该表一次,如果没有属性已更新,在以下时间,Crm采用默认形式从缓存中打开值。

I've trayed registering a plugin at the contact entity, in Retrieve message, updating the userentityuisettings table but I found that Crm only consults the table Once if there is no attribute updated, the following times Crm take the the default form to open value from the cache.

推荐答案

这是一个老问题,但由于即将到来在我对该问题的搜索中,我想添加我的解决方案。

This is an old question but since it's coming up in my searches for this problem I wanted to add my solution.

我们使用Dynamics CRM2013。据我所知,2011年的更高版本也支持该技术。

We use Dynamics CRM 2013. To my knowledge, later versions of 2011 also support this technique.

打开实体时显示的表单由以下几项决定:默认表单,表单的安全角色和后备设置以及表单使用的最后表单该实体的当前用户。我们有一个与问询者类似的问题,我们希望根据表格的值显示不同的帐户表格。我们也厌倦了javascript技术不断受到的重载/刷新。

The form that is displayed when an entity is opened is determined by a few things - the default form, the security roles and fallback settings for a form and the last form used by the current user for that entity. We had a similar problem to the asker where we wanted a different account form displayed based on the value of a form. We were also tired of the constant reload/refresh that javascript techniques are subject to.

我发现了一些博客文章(特别是这篇文章: http://gonzaloruizcrm.blogspot.com/2014/11/avoiding-form-reload-when-switching-crm.html )中提到可以将插件编写到实体的检索中,该插件使您可以从UserEntityUISettings中读取存储最后使用的表单的值(LastViewedFormXml)。如果不是您想要的表格,则可以输入所需的值。这样可以避免刷新JavaScript表单。

I found some blog posts (in particular this one: http://gonzaloruizcrm.blogspot.com/2014/11/avoiding-form-reload-when-switching-crm.html) which mentioned that it is possible to write a plugin to the Retrieve of the entity that allows you to read out the value (LastViewedFormXml) from UserEntityUISettings that stores which form was last used. If it's not the form you want, you can write in the desired value. This avoids the javascript form refreshing.

我不得不修改我发现的示例中的一些代码才能使其正常工作,但我对结果感到满意。您需要使用CrmSvcUtil生成实体类,并将其包含在项目中。您可以从表单编辑器的URL中获取表单指南。

I had to modify some code from the samples I found to get it to work, but I'm happy with the results. You need to generate an entity class using CrmSvcUtil and include it in the project. You can get your form guids from the url of the form editor.

using System;
using System.Collections.ObjectModel;
using System.Globalization;
using System.Linq;
using System.ServiceModel;
using System.ServiceModel.Description;

using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Messages;
using Microsoft.Xrm.Sdk.Query;
using Microsoft.Xrm.Sdk.Client;

namespace CRM.Plugin.AccountFormSwitcher
{
    public class Plugin : IPlugin
    {
        public enum accountType
        {
            Customer =  100000000,
            Vendor =     100000001,
            Partner = 100000002,
            Other =    100000003
        }

        public const string CustomerAccountFormId = "00000000-E53C-4DF4-BC99-93856EDD168C";
        public const string VendorAccountFormId = "00000000-E49E-4197-AB5E-F353EF0E806E";
        public const string PartnerAccountFormId = "00000000-B8C6-4E2B-B84E-729AA11ABE61";
        public const string GenericAccountFormId = "00000000-8F42-454E-8E2A-F8196B0419AF";

        public const string AccountTypeAttributeName = "cf_accounttype";

        public void Execute(IServiceProvider serviceProvider)
        {
            if (serviceProvider == null)
            {
                throw new ArgumentNullException("serviceProvider");
            }

            // Obtain the execution context from the service provider.
            IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));

            ITracingService tracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService));

            IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
            IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);

            var pluginContext = (IPluginExecutionContext)context;
            if (pluginContext.Stage == 20) //pre-operation stage
            {
                var columns = (ColumnSet)pluginContext.InputParameters["ColumnSet"];
                if (!columns.Columns.Contains(AccountTypeAttributeName))
                    columns.AddColumn(AccountTypeAttributeName);
            }
            else if (pluginContext.Stage == 40) //post-operation stage
            {
                EntityReference currentEntity = (EntityReference)context.InputParameters["Target"];
                if (currentEntity == null)
                    return;

                var query = new QueryExpression(Account.EntityLogicalName);
                query.Criteria.AddCondition("accountid", ConditionOperator.Equal, currentEntity.Id);
                query.ColumnSet = new ColumnSet(AccountTypeAttributeName);
                var accounts = service.RetrieveMultiple(query).Entities;
                Account currentAccount = (Account)accounts[0];

                SetForm(currentAccount, service, context.UserId);
            }
        }

        private void SetForm(Account account, IOrganizationService service, Guid userId)
        {
            var query = new QueryExpression(UserEntityUISettings.EntityLogicalName);
            query.Criteria.AddCondition("ownerid", ConditionOperator.Equal, userId);
            query.Criteria.AddCondition("objecttypecode", ConditionOperator.Equal, Account.EntityTypeCode);
            query.ColumnSet = new ColumnSet("lastviewedformxml");
            var settings = service.RetrieveMultiple(query).Entities;

            // Some users such as SYSTEM have no UserEntityUISettings, so skip.
            if (settings == null || settings.Count != 1 || account.cf_AccountType == null) return;

            var setting = settings[0].ToEntity<UserEntityUISettings>();
            string formToUse;
            switch ((accountType)account.cf_AccountType.Value)
            {
                case accountType.Customer:
                    formToUse = String.Format("<MRUForm><Form Type=\"Main\" Id=\"{0}\" /></MRUForm>", CustomerAccountFormId);
                    break;
                case accountType.Vendor:
                    formToUse = String.Format("<MRUForm><Form Type=\"Main\" Id=\"{0}\" /></MRUForm>", VendorAccountFormId);
                    break;
                case accountType.Partner:
                    formToUse = String.Format("<MRUForm><Form Type=\"Main\" Id=\"{0}\" /></MRUForm>", PartnerAccountFormId);
                    break;
                case accountType.Other:
                    formToUse = String.Format("<MRUForm><Form Type=\"Main\" Id=\"{0}\" /></MRUForm>", GenericAccountFormId);
                    break;
                default:
                    formToUse = String.Format("<MRUForm><Form Type=\"Main\" Id=\"{0}\" /></MRUForm>", GenericAccountFormId);
                    return;
            }

            // Only update if the last viewed form is not the one required for the given opportunity type
            if (!formToUse.Equals(setting.LastViewedFormXml, StringComparison.InvariantCultureIgnoreCase))
            {
                var s = new UserEntityUISettings { Id = setting.Id, LastViewedFormXml = formToUse };
                service.Update(s);
            }
        }
    }
}

为了仅通过咨询UserEntityUISettings来解决询问者的问题,我不确定为什么会这样。但是,为什么在更改触发属性时不使用javascript更改表单?我所做的事情并没有遇到插件未显示所需功能的任何问题。

And to address the asker's issue with it only consulting the UserEntityUISettings once, I'm not sure why that's happening. But why not use javascript to change the form when the triggering attribute is changed? That what I do and I haven't ran into any problems with the plugin not displaying the desired for.

这篇关于CRM 2011-如何根据属性值设置默认表单(不使用Javascript)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆