我有一点让我疯狂的要求: 我们有8种不同的联系实体形式。 我们还有一个包含8个选项的选项列表。 我们的想法是,基于所选的选项,我们可以打开Contact记录,默认显示一个特定的表单,不使用JAVASCRIPT以避免性能问题(每个记录必须加载两次)。例如:
形式:
表格1
表格2
表格3
选择列表值 - 默认表单:
表格1 表格2 表格3
如果选择了表格3(选择列表值),则下次打开该记录时,默认情况下应显示表格。
如果选择了表单1(选择列表值),则下次打开该记录时,默认情况下应显示表单。
我已经在systemform实体中注册了一个插件,在RetrieveFilteredForms消息中,更新了userentityuisettings表,我已经能够设置一个" DEFAULT"无论上次打开的表单是什么,每次打开记录时都会显示。
我已经在联系人实体上注册了一个插件,在Retrieve消息中,更新了userentityuisettings表,但我发现Crm只查询表一旦没有更新属性,以下时间Crm采用默认值从缓存中打开值的表单。
答案 0 :(得分:3)
这是一个老问题,但由于我在搜索此问题时出现,我想添加我的解决方案。
我们使用Dynamics CRM 2013.据我所知,2011年的更高版本也支持这种技术。
打开实体时显示的表单由一些内容决定 - 表单的默认表单,安全角色和后备设置以及当前用户为该实体使用的最后一个表单。我们向提问者提出了类似的问题,我们希望根据表单的值显示不同的帐户表单。我们也厌倦了javascript技术所受的持续重载/刷新。
我发现了一些博客帖子(特别是这一篇:http://gonzaloruizcrm.blogspot.com/2014/11/avoiding-form-reload-when-switching-crm.html),其中提到可以在实体的Retrieve中编写一个插件,允许您从UserEntityUISettings中读出值(LastViewedFormXml)哪种形式的商店是最后使用的。如果它不是您想要的形式,您可以写入所需的值。这样可以避免javascript表单刷新。
我必须修改我发现的样本中的一些代码才能使其工作,但我对结果感到满意。您需要使用CrmSvcUtil生成实体类并将其包含在项目中。您可以从表单编辑器的URL获取表单guid。
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来更改表单?我所做的和我没有遇到插件没有显示所需的任何问题。
答案 1 :(得分:0)
编辑:之后指定的OP需要一个没有javascript的解决方案,我留下这个回复以供将来参考。
您可以使用javascript,在OnLoad事件中检查选项列表值并导航到所需的表单。检查此代码作为示例
var value = Xrm.Page.getAttribute("new_optionset").getValue();
switch(value) {
case 100000000:
Xrm.Page.ui.formSelector.items.get(0).navigate();
break;
case 100000001:
Xrm.Page.ui.formSelector.items.get(1).navigate();
break;
case 100000002:
Xrm.Page.ui.formSelector.items.get(2).navigate();
break;
/// ... other cases here
default:
// default form to open when there is no value
Xrm.Page.ui.formSelector.items.get(0).navigate();
}
答案 2 :(得分:0)
这是一个古老而又好的...我使用CRM规则生成隐藏选项卡和显示选项卡操作,这些操作基本上将每个用户角色显示为不同的形式。
步骤:
将表单整理到TABS中,每个标签显示“一种形式”的数据。 (您还可以为每个用户组设置许多TABS)。通常,我创建一个“常规”选项卡,其中包含将设置表单其余部分的密钥选项集,以及角色/用户组/表单中常见的任何字段,如状态,名称等... 3)通过取消选中管理界面中这些选项卡表单属性表单上的可见框,隐藏除常规选项卡以外的所有选项卡。 4)使用CRM规则(crm-rules.com),然后您可以在其中引入元数据,表单以及所有选项卡和部分。然后你只需要为你想要展示的每个'表单'写一个规则......每个规则都是这种格式:
当然,您也可以使用选项集或表单上的任何字段作为条件来执行此操作...此方法的一个好处是,如果用户跨越角色边界(或某些用户属于可以访问多种形式的安全角色),这种技术可以同时显示两种形式......
HTH某人,CRM规则(www.crm-rules.com)生成JavaScript以实现这一目标......