понедельник, ноября 20, 2006

Индексация файлов в списках

В Sharepoint 2.0 существует досадное недоразумение - документы, размещённые в списках как присоединённые файлы, не индексируются через механизм полнотекстового поиска.

С помощью форума выяснилось, что дело в вычисляемом столбце Extension таблицы Docs. Для вычисления значения этого столбца используется формула
case when [DoclibRowId] IS NOT NULL AND charindex(N'.',[LeafName] collate Latin1_General_BIN)>(0) then right([LeafName],charindex(N'.',reverse([LeafName]) collate Latin1_General_BIN)-(1)) else N'' end

Зачем был вставлен выделенный фрагмент, неизвестно (может, ошибки какие пытались исключить?), но для присоединённых файлов это условие, как раз, и выполняется.

Заменой формулы на модифицированную

case when charindex(N'.',[LeafName] collate Latin1_General_BIN)>(0) then right([LeafName],charindex(N'.',reverse([LeafName]) collate Latin1_General_BIN)-(1)) else N'' end

индексация присоединённых файлов включается и все радуются.

суббота, сентября 23, 2006

Sharepoint и history.back

Давно висела задача не дать пользователям возможности уйти с открывшейся страницы не предусмотренным способом с сохранением введённых данных или с удалением незаполненных записей, а при помощи кнопки Back в браузере. Такой "уход" приводит к появлению пустых записей в списках и другим нежелательным эффектам типа воплей о пропавших данных.

При внимательном рассмотрении выяснилось, что "легальная" смена УРЛа происходит при помощи трёх элементов - Button, LinkButton и HyperLink. Для каждого из них требуется специфическое решение для занесения в history адреса перехода (что и даёт эффект "очистки" истории и "блокировки" кнопки Back).

HyperLink

Для этого элемента просто переопределяем реакцию на нажатие:

//Настройка элемента
HyperLink link = new HyperLink();
l
ink.Text = ...;
link.NavigateUrl = ...;
//обработчик нажатия на клиенте
link.NavigateUrl = "javascript:window.location.replace('"+link.NavigateUrl+"')";

LinkButton

Для этого элемента кроме переопределения реакции на нажатие требуется добавить на страницу скрипт и передать в элементе hidden адрес перехода (такая передача требуется на случай, если таких элементов на странице больше одного):

//Настройка элемента
LinkButton linkButton =
new LinkButton();
linkButton.Text = ...;
linkButton.Click += new EventHandler(linkButton_Click);
//обработчик нажатия на клиенте
linkButton.Attributes.Add("onclick", "javascript:SetBack('"+this.ClientID+"')");
//функция настройки адреса перехода
string _backScript = @"<SCRIPT language=""javascript"" type=""text/javascript"" >
var __BackUrl__="""";
function SetBack(id){
var hf=document.getElementById(""_backurl_""+id);
if(hf){ __BackUrl__=hf.value; }
} </SCRIPT>"
;
if(!this.Page.IsClientScriptBlockRegistered("_SetBack"))
   
this.Page.RegisterClientScriptBlock("_SetBack", _backScript);

//функция подмены адреса history.back
string _OnUnloadScript = @"<SCRIPT language=""javascript"" type=""text/javascript"" FOR=window EVENT=onunload>
if(__BackUrl__ != """"){window.location.replace(__BackUrl__);}
</SCRIPT>"
;
if(!this.Page.IsStartupScriptRegistered("_OnUnload"))
   
this.Page.RegisterStartupScript("_OnUnload", _OnUnloadScript);

//адрес перехода
this.Page.RegisterHiddenField("_backurl_" + this.ClientID, <url>);

Button

Для элемента Button настройки аналогичны элементу LinkButton.

 

После таких модификаций переходы по нажатию на такие элементы приводят в "блокировке" кнопки Back браузера.

Естественно, нашлась ложка дёгтя - при наличии на странице других элементов, не обладающих таким же поведением, "блокировка" кнопки Back может быть нарушена. Таким элементом, например, является пункт меню "Изменить общую веб-часть..." :-(

суббота, сентября 16, 2006

XmlViewer и Office Extensions

Объявили ещё зимой конкурс, выставил на него в апреле примочку, до сих пор её "тестируют". Скоро уже никому не надо станет - новая версия Шарепойнта на подходе.

Решил на Гугле вывесить, может, кому пригодится...

P.S. Это веб-часть такая для Шарепонт'а.

XmlViewer and Office Extensions

MSFT have declared even in the winter competition, I have exposed on it in April a lotion, till now "testing". Soon nobody becomes already necessary - new version of Sharepoint on the approach.

Has decided on Google to hang out, maybe to whom it is useful...

It is useful webpart for Sharepoint 2003...

Little toy

For rest and a relaxation has composed utility for copying files on post servers.

Now backup of my the projects I do on a disk by nnbackup and on mail servers (gmail, hotmail, mail.ru) by eMailBackup - there should be an advantage of greater boxes, not only a spam to collect...

Игрушечка

Для отдыха и расслабления сочинил утилитку для копирования файлов на почтовые серверы.

Теперь бекап своих проектов делаю на диск при помощи nnbackup и на почту (gmail, hotmail, mail.ru) при помощи eMailBackup - должна же быть польза от больших ящиков, не только спам собирать...

суббота, сентября 02, 2006

Правка настроек.

В приложении использую конфиг-файл, в котором пользователи пишут значения руками. Естественно, ляпают. Как правило, лишние символы в конце и в начале. Но соответствующие свойства класса Settings оказываются readonly (настройки для всего приложения). Да к тому же тип у настроек - StringCollection.

В итоге пришлось соорудить функцию

public delegate bool goodString(string o);
public delegate string clearString(string o);

public
StringCollection CloneCollection(StringCollection src, goodString goodFunc, clearString clearFunc) {
  
StringCollection rv = new StringCollection();
  
foreach (string t in src) {
     
string tc = clearFunc == null ? t : clearFunc(t);
     
if (goodFunc == null || goodFunc(tc))
         rv.Add(tc);
   }
  
return rv;
}

Вызов такой:

setsSearchSites = CommonTools.CloneCollection(sets.SearcSites,
delegate(string s) { return !string.IsNullOrEmpty(s); },
delegate(string s) { return s.Trim().TrimEnd("/".ToCharArray()); });

А в приложении пользуюсь уже исправленной копией параметров, с вычищенными пробелами и слешами на концах.

суббота, августа 19, 2006

Шутки от MS SQL Server - 2

(по крайней мере, MS SQL 2005 так шутит)

Выяснилось, что даже при указании для некоторого NOT NULL поля таблицы значения по умолчанию в это поле нельзя записывать null.

Т.е., если поле col1 определено как NOT NULL default ('anystring'), то нельзя написать INSERT INTO (col0, col1) VALUES (@p0, @p2) и параметру @p2 присвоить null (DBNull.Value). Тут получится выкидыш-exception - низя в такое поле совать NULL. В этой ситуации поле нужно вовсе в списки не упоминать, тогда ему будет присвоено значение по умолчанию.

Как-то это неочевидно, а в BOL если и написано об этом, то где-то весьма далеко - специально искал, да не нашёл.

Шутки от MS SQL Server

(по крайней мере, SQL EveryWhere так шутит)

Запоминаю в таблице данные файла (имя и дату изменения), чтоб в дальнейшем повторно этот файл не обрабатывать. Фокус вылезает при извлечении запомненной даты и сравнении её с датой из файловой системы. Если файл не изменялся, результат такого сравнения - как у блондинки: то ли больше, то ли меньше. Выяснилось, что при сохранении пропадают сколько-то миллисекунд (округление такое, что ли?)... Пришлось изобретать округление до секунды и пользоваться такими округлёнными значениями.

public static DateTime RoundToSecond(DateTime date) {
           
return new DateTime(
            date.Year, date.Month, date.Day,
           date.Hour, date.Minute, date.Second);
}

пятница, августа 18, 2006

Пост из Writer

Новую примочку придумали. Поглядим...

Как-то не сразу постится...

private void DoFile(string path) {
         iisLogsTested++;
        if (TestFileToProcess(path)) {
              log.WriteFileWithTimeStamp(
"Processing of file [{0}]", path);
              ProcessFile(path);
        }
  }

Нормально, вроде. Пользоваться можно.

P.S. Одновременно с этой примочкой поставили тулбар, с которым моя машина не справляется :-( Пришлось снести...

вторник, августа 08, 2006

Бесплатный антивирус в Windows 2003

Жлобятся производители антивирусов дать возможность  запускать бесплатные версии на Windows 2003. А без антивируса как-то неуютно.
Поднапрягся,  настроился на работу с ClamWin - бесплатный, по размеру небольшой, Outlook проверяет на ходу, базы обновляют довольно оперативно, да и плохого про него не слышно. Одного не хватает - нет резидентного файлового сканера. Да и программка обновления баз в трее великовата.  
Сделал вот как: 
1. Программку из трея прогнал, заменил её задачей nnCron'а :Time: 17 */3  * * * *
Action:
ONLINE?IFStartIn: "G:\avir\.clamwin" ShowMinimized NormalPrioritySTART-APP: D:\Program Files\ClamWin\bin\freshclam.exe --config-file=G:\avir\.clamwin\freshclam.cfg --log=G:\avir\.clamwin\log\ClamUpdateLog.txt --datadir=G:\avir\.clamwin\db --quietTHEN
2. Вместо сканера настроил программку LogMon на сканирование новых файлов в каталоге My Downloads (сюда загружаю файлы из Сети). Команда для этого:
D:\Program Files\ClamWin\bin\clamscan.exe -d G:\avir\.clamwin\db --tempdir=g:\temp\ClamvByaka - l G:\avir\.clamwin\log\ClamScanLog.txt "%File="DP\\N.E"" 
3. Сгружальщик FlashGet настроил на выполнение для каждого загруженного файла команды сканирования D:\Program Files\ClamWin\bin\clamscan.exe -d G:\avir\.clamwin\db -- tempdir=g:\temp\ClamvByaka -l G:\avir\.clamwin\log\ClamScanLog.txt
Жить можно...

пятница, июля 28, 2006

Ghost from SharePoint

Потребовалось сделать обход всех существующих структур Шарепойнта и достать все библиотеки документов и рисунков. Выяснилось, что в базе существует много объектов, которых как бы и нет (на страницах не отображаются), но в объектную модель попадают. На них вылетают всякие исключения, которых вовсе не ожидаешь, но которые в итоге следует учитывать. После всех этих «учётов» ожидаемый метод из 10 строк вылился вот во что (здесь log – мой собственный логгер, к делу не относится):
 
/// <summary>
///
Выдаёт все библиотеки документов

/// </summary>

/// <returns>очередную библиотеку </returns>

/// <remarks>вызывать в цикле вида

/// foreach (SPDocumentLibrary lib in DocLibs()){ ... }

/// </remarks>

IEnumerable< SPDocumentLibrary>DocLibs() {

    SPGlobalAdmin ga = new SPGlobalAdmin();

    string[] vsNames = ga.VirtualServerNames;

    for(int vs=0;vs<vsNames.Length;vs++){

        SPVirtualServer srv = null;

        try {

            srv = ga.VirtualServers[vs];

        } catch (Exception err) {

            log.WriteException(err, false, vsNames[vs], 68);

            continue;//next VirtualServer

        }

        int nSites = -1;

        try {

            nSites = srv.Sites.Count;

        } catch { }

        if (nSites > 0) {

            string[] siteNames = new string[srv.Sites.Count];

            for (int s = 0; s < siteNames.Length; s++)//fill names

                try {

                    siteNames[s] = srv.Sites[s].Url;

                } catch {

                    siteNames[s] = null;

                }

            foreach (string siteName in siteNames) {

                if (string.IsNullOrEmpty(siteName)) continue; //next Site

                SPSite site = null;

                try {

                    site = new SPSite(siteName);

                } catch (Exception err) {

                    log.WriteException(err, false, siteName, 69);

                    continue; //next Site

                }

                site.CatchAccessDeniedException = false;

                string[] webNames;

                try {

                    webNames = site.AllWebs.Names;

                } catch (Exception err) {

                    log.WriteException(err, false, siteName, 691);

                    continue; //next Site

                }

                foreach (string webUrl in webNames) {

                    SPWeb web = null;

                    try {

                        web = site.AllWebs[webUrl];

                    } catch (Exception err) {

                        log.WriteException(err, false, webUrl, 70);

                        continue;//next web

                    }

                    int listsCount=-1;

                    try {

                        listsCount=web.Lists.Count;

                    } catch { }

                    if (listsCount > 0) {

                        string[] listNames = new string[listsCount];

                        for (int l = 0; l < listsCount; l++) {

                            try {

                                listNames[l] = web.Lists[l].Title;

                            } catch (Exception err) {

                                log.WriteException(err, false,

                                         string .Format("List number {0}", l + 1), 71);

                                 listNames[l] = string.Empty;

                             }

                         }

                         foreach (string listName in listNames) {

                             if (!string.IsNullOrEmpty(listName)) {

                                 SPList list = null;

                                 try {

                                     list = web.Lists[listName];

                                 } catch (Exception err) {

                                     log.WriteException(err, false, listName, 72);

                                     continue; //next List

                                 }

                                 if (list != null && list is SPDocumentLibrary)

                                     yield return list as SPDocumentLibrary;

                             }

                         }

                     }

                     web.Dispose();                }

                site.Dispose();            }

        }

    }

    ga.Dispose();

}

понедельник, июля 24, 2006

Опять прикол от SharePoint

Нужно было воспользоваться свойством списка list.LastItemModifiedDate - gets the date and time that an item, field, or property of the list was last modified.

При этом время выдаётся по Гринвичу независимо от региональных установок на объектах SPWeb и SPSite. Выкрутился использованием конструкции
  list.ParentWeb.RegionalSettings. TimeZone.UTCToLocalTime(list.LastItemModifiedDate )

В это же самое время для отдельных items списка данные, например, list.Items [0]["Modified"], выдаются в соответствии с региональными установками.

Вот же, блин. Горелый.

четверг, июля 13, 2006

Встраиваемые СУБД

В проекте потребовалось сохранять промежуточные данные, чтоб потом их считывать. Можно, конечно, сериализовать и сохранять в файл (двоичный или xml), но подумалось, что попользоваться базой данных проще и привычней. База там, естественно, есть, однако это MS SQL Server, занятый своей собственной неслабой работой, поэтому сразу решил поискать чего-то встраиваемого в саму программу, небольшого размера и, желательно, бесплатного.

Вот результаты изысканий:

Vieka eSQL – бесплатная для любого применения, платить нужно только при использовании в продажных продуктах для мобильных девайсов. Для использования требуются библиотеки размером ок. 450 кб. Наследник SQLite, имеет минимальный набор типов, с небольшими базами работает быстро (при размерах в сотни мегабайт народ жалуется на тормоза). Имеет интерфейс с .NET, работает с SQL-92. База однофайловая. Требуются операции сжатия базы. Имеется пример, который получается изменять – бум смотреть в качестве кандидата.

db4o
– распространяется по GPL. Для использования требуются библиотеки размером ок. 860 кб. Имеется интерфейс с .NET 2.0 и .NETCF 2.0. Объектная база. Народ жалуется на задержки при открытии файла базы. База однофайловая. Мало какой-либо хорошей информации, хотя имеющиеся примеры работают.

SQL Server Everywhere Edition – пока что существует в виде CTP, но к концу года обещают выпустить релиз, да ещё и бесплатный. Для использования требуются библиотеки размером ок. 1.5 Мб. Имеется интерфейс с .NET 2.0 и .NETCF 2.0. Программная модель – как у SQL Server 2005. База однофайловая. Штука привлекательная, надо её поизучать на будущее.

VistaDB – продаётся за деньги, но лицензия позволяет распространять использующий базу продукт бесплатно. Для использования требуются библиотеки размером ок. 650 кб. Имеется интерфейс с .NET 2.0, работает с SQL-92. Также имеется интерфейс DDA – прямой доступ к данным, быстрая работа на низком уровне с таблицами, записями и т.д. Набор типов почти как у SQL Server. База однофайловая. Примеры работают, поддаются изменению.

Пост из Word 2007

Обнаружилась встроенная фича – постить в блоги.

Щас и проверим.


Это наляпано в Word’е 2007 beta2

Всё, вроде, ничего, даже постит в блоги на Sharepoint 2007. Повторный пост воспринимается как новый, в Шарепойнте заменяет старый.

среда, июля 05, 2006

Sharepoint 2007

После установки Office Sharepoint Server:
 
в Рефлекторе вот такое -
[Obsolete( "This class is obsolete.")]
public class Area{ ... }
И все портальные структуры тоже. Слава богу, что от чепухи отказались.

Добавились разные хитрые шаблоны узлов и сервисы, но на моём тестовом "сервере" они не фурычат (жидковата машинка, конечно).
 

вторник, июля 04, 2006

Sharepoint 2007 (WSS v.3)

Из того, что пока увиделось (повозился с WSS 3):
  • блог и WiKi - вполне рабочие сайты.
  • Discussion - уже совсем на форум похожа, хоть с мелкими глюками.
  • Списки - в ссылочных полях можно делать множественный выбор, список с другого сайта подключить не получилось (хотя и были разговоры о подобных пряниках).

 

четверг, июня 29, 2006

Срок службы Windows Server 2003.

Экспериментально установился, на собственной шкуре (вернее, на компьютере).
 
Установлена система была в 2002 г. (upgrade с Server 2000 через RC). Машина использовалась в качестве стенда:
  • Sharepoint 2001
  • Sharepoint 2003, sp1, sp2
  • MS SQL 2000, sp1, sp3
  • MS SQL 2005, sp1
  • Oracle 7,8,9
  • Pervasive
  • Галактика разных версий
  • антивирусы/firewall'ы разные
  • всякое другое по мелочам (чистилки реестра, дефрагментаторы, архиваторы и проч. ФАРы)
Ставилось, сносилось, работало в разнообразных комбинациях. Переустанавливалась в режиме обновления с сохранением всех настроек один раз в начале 2006 г.
 
Вчера пришлось переустановить с полной очисткой диска - новый софт уже не ставился - .NET 3, Sharepoin 2007.
Бум смотреть, на сколько теперь хватит.

среда, июня 28, 2006

Приколы SQL 2005.

При установке получил сообщение:
 
Could not get performance counter registry info for msftesqlFD for instance SQL2K5 due to the following error : The operation completed successfully
 
Хи-хи. 

понедельник, июня 26, 2006

Приколы продолжаются

Друзья из MS статейку на днях вывесили. Теперь придётся код перебирать, чтоб ихние рекомендации реализовать.

In scenarios in which you use SharePoint objects extensively―for example, in SharePoint sites that use custom Web Parts―you can cause the following unusual behaviors by not disposing of those objects that can be disposed of:
  • Frequent recycles of the Microsoft Windows SharePoint Services application pool, especially during peak usage
  • Application crashes that appear as heap corruption in the debugger
  • High memory use for Microsoft Internet Information Services (IIS) worker processes
  • Poor system and application performance

Several of the Windows SharePoint Services objects, primarily the SPSite class and SPWeb class objects, are created as managed objects. However, these objects use unmanaged code and memory to perform the majority of their work. The managed part of the object is small; the unmanaged part of the object is much larger. Because the smaller managed part of the object does not put memory pressure on the garbage collector, the garbage collector does not release the object from memory in a timely manner. The object's use of a large amount of unmanaged memory can cause some of the unusual behaviors described earlier. Calling applications that work with IDisposable objects in Windows SharePoint Services must dispose of the objects when the applications finish using them. You should not rely on the garbage collector to release them from memory automatically.

Вроде, пару лет назад всего этого никто не знал... И, самое смешное, и в "новой" версии всё так же и осталось.

воскресенье, июня 18, 2006

Indigo(WCF) & Win Mobile 5.0

Не нашлось способа подключиться к WCF-сервису в программе для Windows Mobile 5.0.

Облом происходит на строчке
EndpointAddress address = new EndpointAddress (svcUri, null);
Рассказывает, что cannot convert from 'System.Uri [g:\Program Files\Microsoft.NET\SDK\CompactFramework\v2.0WindowsCE\System.dll]' to 'System.Uri'
Получается, что эти самые URI в "большом" FW и в CF - совсем уж непохожие.
В общем, опять недоделка...
Бум пока через веб-сервис, по старинке.

четверг, июня 15, 2006

PROMT.

На форуме навели на мысль - сделать в портале "встроенный переводчик". Получилось не хуже Research-панели от Офиса.

пятница, июня 09, 2006

Sharepoint - очередной прикол.

При чтении данных списка посредством вызова метода GetList веб-сервиса http://Server_Name/[sites/][Site_Name/]_vti_bin/Lists.asmx получаем исключение с сообщением "There is an error in XML document (94, 5)." И всё.
Выяснилось, что в текстовом поле списка имеется символ \0x31. Откуда взялся, неведомо, да и не повод это для такого поведения. Тем более, при чтении через объектную модель ничего плохого не происходит. Рисуется квадратик на месте символа.

P.S. Что означают числа 94,5 в сообщении, выяснить так и не удалось. India forever.

среда, мая 24, 2006

WSS Login

Многие сомневаются в существовании означенной веб-части. Вот же она - в виде кнопки "Вход":


вторник, апреля 18, 2006

Sharepoint WebParts in VS 2005

Последнее усилие получить что-то пристойное в смысле использования Visual Studio 2005 для разработки WebPart'ов для Sharepoint'а.
Вот здесь - шаблон проекта. С его помощью создаётся вполне работоспособное хозяйство для разработки и компиляции веб-частей.
Где-то также нашлись codesnippet'ы, но не очень интересные, по-правде. В общем, для редактирования 2005-я студия получше будет.
Только вот с отладкой - никак, 2005-я нужного режима вовсе не имеет. Сделал проект на 2003-й Студии, включил туда тексты (отладка не запускается без компиляции) - и можно отлаживать. Если не очень часто это делать - пригодно для жизни получилось.

воскресенье, апреля 16, 2006

Очередной прикол Sharepoint

При копировании списков для полей типа SPFieldNumber использовал конструкцию:

newfield.MaximumValue = field.MaximumValue;

newfield. MinimumValue = field.MinimumValue;

Первая строчка проходит, на второй же вылетает исключение с сообщением типа "Значение сильно большое или сильно маленькое для типа Double". Проходит только значение по умолчанию (ок. -1e308, когда значение не устанавливалось), если в исходном списке такое значение было установлено, то кранты. Через Reflection нужное значение присвоить тоже не удаётся. :-(
Хуже того, исполнение первой строчки вызывает то же исключение при попытке отредактировать это поле в интерфейсе _layouts/1049/FldEdit.aspx.

Пришлось в Админе от установки этих свойств отказаться с выдачей предупреждения.

Вот, блин.

понедельник, марта 27, 2006

MSMQ on Windows Mobile 5

Решил попользоваться означенной фигнёй.
Скачал дистрибутив, установил – не работает :-(
Порылся в Гугле, выяснилось, что это у многих так. Но поправимо – надо руками активировать сей девайс:

[DllImport("coredll.dll",CharSet=CharSet.Unicode)]
public static extern IntPtr ActivateDevice(string lpszDevKey, int dwClientInfo);
...
IntPtr id = ActivateDevice(@"Drivers\BuiltIn\MSMQD", 0);
...

После этого хозяйство подаёт признаки жизни.

Дальше сделал попытку создать очереди и сунуть в них сообщения – ну, по примерам в MSDN и проч. литературе.
private void Testmenu_Click(object sender, EventArgs e) {
Qname = @"FormatName:DIRECT=OS: DkmServ\qtek";
Qname = @".\Private$\ttrqueL";
Qname = @".\ttrqueP"; MessageQueue.GetMachineId(".");
if (!MessageQueue.Exists(Qname)) {
msgs = MessageQueue.Create(Qname);
} else {
msgs = new MessageQueue(Qname);
}
msgs.Send("Hello, Прювет");
} catch (Exception err) {
MessageBox.Show(err.Message, err.GetType().Name);
}
}

Выяснилось, что можно оперировать только с приватной очередью, все прочие вариантыпадают. Да ещё с сообщением о невозможности вывести сообщение в связи с отсутствием какой-то нужной для этого сборки.
В общем, очередная недоделка. Пущай полежит до следующей версии. Программки на одной машине как-нить и без MSMQ согласую.

четверг, марта 16, 2006

Очередной прикол Sharepoint

Обнаружил, что в одном месте - в базе данных содержимого Sharepoint (в случае портала - в базе portal1_SITE) в таблице Sites (поле FullUrl ) пишутся абсолютные значения адресов (наподобие http://server/sites/site1).
Пишутся они туда только для узлов верхнего уровня в момент их создания и, похоже, больше нигде не используются. Вместо них можно свободно написать любые матерные слова, сайты работают нормально.
Во всех остальных местах пишутся относительные адреса сайтов и узлов.

Реликт какой-то, похоже...

воскресенье, марта 05, 2006

Секреты, едрёныть :(

Возился с задачами Outlook на десктопе и на мобиле. Всё хорошо и красиво, синхронизируются, можно что-то записать, записанное хранится.Но только на первый взгляд. На второй взгляд – неясно, как синхронизируется: идентификаторы на десктопе и на мобилке друг на друга вовсе не похожи. Где-то ещё таблицы должны храниться...Кроме того, добавляемые пользовательские свойства (даже с одинаковыми именам) не пересылаются. Вот же блин!

суббота, февраля 11, 2006

Очередной прикол Sharepoint'а

Теперь прикол от Sharepoint Portal.

При копировании веб-части в файл столкнулся с тем, что иногда имеет значение порядок присваивания некоторых свойств веб-части.
Например, свойство ZoneID следует назначать после добавления новой веб-части к целевой коллекции.

WebPart dst = new WebPart ();
SPWebPartCollection wpc = file.GetWebPartCollection(Storage
.Shared);
Guid
ID = wpc.Add(dst);
WebPart ds = wpc[ID];
//добавленный контрол
ds.ZoneID = ZoneID;
//присвоить значения другим свойствам
wpc.SaveChanges(ID);

Оказалось, на страницах портала есть зоны (одна из них - TitleBar), которым небезразличен порядок действий.

пятница, февраля 10, 2006

Sharepoint & Anthem.NET

Nice work Anthem.NET I used in the small Web-part, containing TextBox and LinkButton . For the conclusion of communications there is Label control.

The method of use came out sufficiently simple.
Connecting to namespace Anthem:
#if AJAX
using
Anthem;
#else
using System.Web.UI.WebControls;
#endif

Addition of specific properties in method OnInit:
#if AJAX
btn.TextDuringCallBack = "..Wait";
btn.EnabledDuringCallBack = false;
#endif

Everything earned after this, as it was expected:
- the button is blocked to the period of the fulfillment of actions, the inscription is derived on it"..Wait"
- on the return draw again only changed elements (button, label and text field), without the stupid pulling of the entire page.

Underwater stones thus far were located two:
1. During the changes in js-code and the recompilation of project Anthem-2003 is necessary cleaning AppPool the corresponding Web site.
2. Values UpdateAfterCallBack=true; in method OnInit to establish one ought not - immediately occurs copying with the original values. To establish them is possible either in the events handlers or in the beginning of method RenderWebPart.

Sharepoint & Anthem.NET

Отличную разработку Anthem.NET использовал в небольшой веб-части, содержащей TextBox и LinkButton (не считая выполняемых действий). Для вывода сообщений имется Label.

Метод использования получился довольно простой.

В файле вебчасти, использующей web-контролы, подключил пространство имён Anthem:
#if AJAX
using Anthem;
#else
using System.Web.UI.WebControls;
#endif

В методе OnInit для имеющейся на веб-части кнопки btn добавил cпецифические свойства:
#if AJAX
btn.TextDuringCallBack = "..Wait";
btn.EnabledDuringCallBack =
false;
#endif

Собственно, после этого всё заработало, как и ожидалось:
- на время выполнения действий кнопка блокируется, на ней выводится надпись "..Wait"
- по возврату перерисовываются только изменившиеся элементы (кнопка, метка и текстовое поле), без дурацкого дёргания всей страницы.

Подводных камней пока нашлось два.
1. При изменениях в js-коде и перекомпиляции проекта Anthem-2003 необходима очистка AppPool соответствующего веб-сайта.
2. Значения UpdateAfterCallBack=true; в методе OnInit устанавливать не следует - сразу происходит перерисовка исходными значениями. Устанавливать их можно или в обработчиках событий или в начале метода RenderWebPart.

четверг, февраля 09, 2006

«About» ToolPart continued

В развитие примочки перенёс в эту панель запуск функции, которая запускалась из меню веб-части и не давала покоя любопытным юзерам. Сделал там кнопочку, всё хорошо, всё выполняется. Ура!

Но Microsoft не дремлет! И тут нашлась засада...

При выполнении функции изменяются некоторые свойства веб-части, однако их значения в панели настройки при этом никак не изменяются. При нажатии кнопок ОК и Применить (большинство юзеров, естественно, на них и нажимает) происходит перезапись свойств старыми значениями.
Пришлось эти кнопки убрать и оставить только крестик в правом верхнем углу.

ParentToolPane.OK.Visible =
ParentToolPane.Cancel.Visible =
ParentToolPane.Apply.Visible = false;

Минное поле...

пятница, января 27, 2006

«About» ToolPart

Подсмотрел у кого-то и поразвивал примочку для вывода панельки «About…» в панели настройки веб-части.
Сам класс панели :

public class About: Microsoft.SharePoint.WebPartPages .ToolPart
{
      public About()
      {
            this . Title = "O
веб -части..." ;
      }
      string bCard="© DkmS, 2005..06 ";
      /// <summary>
      /// Parent Webpart
      /// </summary>
      public WebPart ParentWP{
            get{return parent;}
            set {parent= value;}
      }
      protected override void OnInit(EventArgs e) {
            base .OnInit (e);
      }
      public override void ApplyChanges(){}
      public override void SyncChanges(){}
      public override void CancelChanges(){}
      protected override void RenderToolPart(HtmlTextWriter output){
            output .Write("<center>" );
            output.Write( "<div title='"+bCard +"'>");
            output.Write("<br><b>My cool WebPart.</b><br><br>" );
            output.Write("</div>");
            output . Write("</center>");
            output.Write("<br><br><hr>" );
      }
}

Использование:

В вызывающем классе изменяем метод

public override ToolPart[] GetToolParts() {
      ToolPart[] baseTP = base .GetToolParts ();
      ToolPart[] myTP =new ToolPart[3];
      WebPartToolPart std=baseTP[ 0] as WebPartToolPart;
      CustomPropertyToolPart myprops=baseTP[1] as CustomPropertyToolPart;
      myTP[0]=myprops;

      myTP[2]=std;
      About about=new About();
      about.ParentWP= this;
      myTP[1]=about;
      return myTP;
}