问题
Is there a way to always have the selected items in a Sitecore Treelist sorted alphabetically?
回答1:
No, but you could look in to creating your own 'sorted treelist'. Someone asked a different question earlier today but it has basically the same answer:
Sitecore Tree list datasource - VersionExist
Sitecore lets you create custom field types. They can be based on existing ones, but with some added tweaks.
As mentioned in the answers to the other question, here are 2 articles which are good places to start:
Creating a Composite Custom Field
Apply Dynamic TreeList Source Parameters with the Sitecore ASP.NET CMS
Here's my implementation, which although long, is mostly copy-and-pasted from the decompiled Treelist code. I've highlighted which bits which are new in the Value property and the Add method:
namespace CustomFieldTypes
{
public class Treelist : Sitecore.Shell.Applications.ContentEditor.TreeList
{
public override string Value
{
get
{
// ---------- New code here -----------
var ids = base.Value.Split('|');
var db = Sitecore.Configuration.Factory.GetDatabase("master");
var items = ids.Select(id => db.GetItem(id)).Where(item => item != null);
var orderedItems = items.OrderBy(item => item.Name);
var orderedIds = orderedItems.Select(item => item.ID.ToString());
return String.Join("|", orderedIds);
// ---------------------------------------
}
set
{
base.Value = value;
}
}
protected void Add()
{
if (this.Disabled)
return;
string viewStateString = this.GetViewStateString("ID");
TreeviewEx treeviewEx = this.FindControl(viewStateString + "_all") as TreeviewEx;
Assert.IsNotNull((object) treeviewEx, typeof (DataTreeview));
Listbox listbox = this.FindControl(viewStateString + "_selected") as Listbox;
Assert.IsNotNull((object) listbox, typeof (Listbox));
Item selectionItem = treeviewEx.GetSelectionItem();
if (selectionItem == null)
{
SheerResponse.Alert("Select an item in the Content Tree.", new string[0]);
}
else
{
if (this.HasExcludeTemplateForSelection(selectionItem))
return;
if (this.IsDeniedMultipleSelection(selectionItem, listbox))
{
SheerResponse.Alert("You cannot select the same item twice.", new string[0]);
}
else
{
if (!this.HasIncludeTemplateForSelection(selectionItem))
return;
SheerResponse.Eval("scForm.browser.getControl('" + viewStateString + "_selected').selectedIndex=-1");
ListItem listItem = new ListItem();
listItem.ID = Sitecore.Web.UI.HtmlControls.Control.GetUniqueID("L");
// ----- New Code Here -----------------------
bool listItemAdded = false;
for (int i = 0; i < listbox.Controls.Count; i++ )
{
ListItem control = (ListItem)listbox.Controls[i];
if (control == null)
return;
if (String.Compare(GetHeaderValue(selectionItem), control.Header) < 0)
{
listbox.Controls.AddAt(i, listItem);
listItemAdded = true;
break;
}
}
if (!listItemAdded)
{
Sitecore.Context.ClientPage.AddControl((System.Web.UI.Control)listbox, (System.Web.UI.Control)listItem);
}
// ------------------------------------------
listItem.Header = this.GetHeaderValue(selectionItem);
listItem.Value = listItem.ID + (object) "|" + (string) (object) selectionItem.ID.ToString();
SheerResponse.Refresh((Sitecore.Web.UI.HtmlControls.Control) listbox);
SetModified();
}
}
}
protected static void SetModified()
{
Sitecore.Context.ClientPage.Modified = true;
}
private bool HasIncludeTemplateForSelection(Item item)
{
Assert.ArgumentNotNull((object)item, "item");
if (this.IncludeTemplatesForSelection.Length == 0)
return true;
else
return HasItemTemplate(item, this.IncludeTemplatesForSelection);
}
private bool HasExcludeTemplateForSelection(Item item)
{
if (item == null)
return true;
else
return HasItemTemplate(item, this.ExcludeTemplatesForSelection);
}
private bool IsDeniedMultipleSelection(Item item, Listbox listbox)
{
Assert.ArgumentNotNull((object)listbox, "listbox");
if (item == null)
return true;
if (this.AllowMultipleSelection)
return false;
foreach (Sitecore.Web.UI.HtmlControls.Control control in listbox.Controls)
{
string[] strArray = control.Value.Split(new char[1]
{
'|'
});
if (strArray.Length >= 2 && strArray[1] == item.ID.ToString())
return true;
}
return false;
}
private static bool HasItemTemplate(Item item, string templateList)
{
Assert.ArgumentNotNull((object)templateList, "templateList");
if (item == null || templateList.Length == 0)
return false;
string[] strArray = templateList.Split(new char[1]
{
','
});
ArrayList arrayList = new ArrayList(strArray.Length);
for (int index = 0; index < strArray.Length; ++index)
arrayList.Add((object)strArray[index].Trim().ToLowerInvariant());
return arrayList.Contains((object)item.TemplateName.Trim().ToLowerInvariant());
}
}
}
When this is compiled and in your application you need to go to /sitecore/system/Field types/List Types/Treelist
in the core database. In there, you need to fill in the Assembly
and Class
fields, and clear out the Control
fields.
回答2:
You could create a custom field and sort the items in the selected list using generics, then save the guids back to the field. I covered this in a recent blog post. There isn't that much coding involved.
来源:https://stackoverflow.com/questions/21462117/how-to-sort-the-selected-items-in-a-sitecore-treelist