Установка поля поиска для текущего элемента в списке
-
10-12-2019 - |
Вопрос
мой вариант использования:
Я пытаюсь реализовать систему управления событиями в SharePoint, используя визуальные веб-части.
У меня есть два пользовательских списка, один называется «События».Допустим, у него есть столбец «Название», который показывает сведения о событии в форме отображения (на самом деле это стандартное поле заголовка) и некоторые другие нерелевантные детали в других столбцах.
Второй список называется «Участники».Есть две колонки: первая:«Посетитель» (пользовательское поле, в котором указывается логин текущего пользователя).Второй:«Событие» (на данный момент:Строка названия события).
В моей визуальной веб-части (добавленной с помощью &ToolPaneView=2 выше формы отображения списка «События») я показываю кнопки («зарегистрироваться» и «отменить регистрацию») в зависимости от следующего кода:
...
using System.Linq;
...
//Snippet of prerequisites for better understanding
SPWeb web = SPContext.Current.Web;
SPUser currentUser = web.CurrentUser;
SPListItem currentEventItem = (SPListItem)SPContext.Current.Item;
string userString = currentUser.ID.ToString() + ";#" + currentUser.LoginName.ToString();
...
//called in page_load
private void GetButtonView()
{
try
{
bool foundUsers = (from SPListItem item in tn.Items
where item["Attendee"].ToString() == userString
&& item["Event"].ToString() == currentEventItem.Title
select item).Count() > 0;
if (foundUsers)
{
...
ButtonRegister.Visible = false;
}
else
{
...
ButtonUnregister.Visible = false;
}
}
catch (Exception ex)
{
...
}
}
Проблема в этом варианте использования:Если заголовок события («Название») будет изменен позже в списке событий, я не получу правильного сопоставления участника => события, потому что в данный момент я проверяю только соответствие строк заголовка.
Предпочтительное решение:Сделайте столбец «Событие» в списке «Посетители» столбцом поиска, который получает фактическое событие (я думаю, идентификатор и название) и показывает заголовок в столбце «Событие» списка «Посетители», поэтому, если заголовок изменен позже в списке «События» список участников автоматически обновит ссылающиеся записи в столбце «Событие», и я смогу отобразить кнопку «Зарегистрироваться»/«Отменить регистрацию» (не считая правильного сопоставления, которое обязательно надо ;) ).
Было бы здорово, если бы кто-нибудь мог дать мне решение/подсказку, как сделать это программно, потому что у меня это не работает.
С уважением, Доминик
п.с.Я немец, поэтому надеюсь, что вы понимаете мой вопрос.Не стесняйтесь спрашивать более подробную информацию!Я постараюсь объяснить это на правильном английском языке.
редактировать 1:Вот мой метод addAttendee:
private void AddAttendee() {
try
{
//Using this because read-permissions are used for attendees
SPSecurity.RunWithElevatedPrivileges(delegate()
{
using (SPSite ElevatedSite = new SPSite(site.ID))
{
using (SPWeb ElevatedWeb = ElevatedSite.OpenWeb(web.ID))
{
SPList attendeeList= ElevatedWeb.Lists["Attendees"];
SPListItemCollection listItems = attendeeList.Items;
SPListItem item = listItems.Add();
item["Name"] = currentUser.ID.ToString() + ";#" +
currentUser.LoginName.ToString() + ";#";
item["Event"] = currentEventItem["Title"];
ElevatedWeb.AllowUnsafeUpdates = true;
item.Update();
ElevatedWeb.AllowUnsafeUpdates = false;
...
}
}
});
}
catch (Exception ex)
{
...
}
}
Решение
Насколько мне известно, изменение типа поля с текста на поиск не поддерживается в Sharepoint.
Вам следует создать новое поле поиска в списке «Посетители» и указать его в списке «События» либо из настроек списка Sharepoint, либо из кода.
По сути, поле поиска имеет ту же структуру, что и пользовательское поле, которое вы заполнили в последнем фрагменте вашего кода — ID#;Title.Кроме того, значение поля поиска представлено классом SPFieldLookupValue, поэтому его можно получить следующим образом:
return new SPFieldLookupValue((string)item["EventLookup"]);
Вы можете установить значение поля поиска, назначив новый объект SPFieldLookupValue свойству SPListItem:
item["EventLookup"] = new SPFieldLookupValue(1, "Great Event");
где 1 — идентификатор элемента списка событий, а «Великое событие» — название элемента списка событий.
Если я также могу добавить некоторые замечания к вашим примерам кода.Насколько я вижу, вы ищете участников мероприятия, перебирая объект SPList.Items и сравнивая строковое значение поля «Посетитель» с пользовательским строковым значением.
Такой поиск может возвращать неправильные и медленные результаты, поскольку обычно поле поиска пользователя содержит отображаемое имя пользователя, а не имя для входа.Вместо этого я бы рекомендовал использовать запрос CAML:
SPQuery qry = new SPQuery();
qry.Query =
" <Where>"
+" <And>"
+" <Eq>"
+" <FieldRef Name='Event' />"
+" <Value Type='Text'>"+ currentEventItem.Title +"</Value>"
+" </Eq>"
+" <Eq>"
+" <FieldRef Name='Attendee' LookupId='TRUE' />"
+" <Value Type='Integer'>"+ currentUser.ID.ToString() +"</Value>"
+" </Eq>"
+" </And>"
+" </Where>";
SPListItemCollection listItems = spList.GetItems(qry);
bool foundUsers = listItems.Count > 0;
Приведенный выше запрос выполняет поиск по полю «Событие» (введите «текст», как в вашем примере) и по идентификатору пользователя участника без имени входа пользователя.Кроме того, он извлекает только те элементы, которые попадают в условие запроса.