Question

arrière-plan: La société que je travaille a une liste SharePoint régulière avec un contenu personnalisé (qui n'hérite pas d'un élément de liste de calendrier) qu'il utilise pour des événements. Il montre alors ceux-ci à l'aide d'une vue de calendrier. Semble assez simple. Nous avons la nécessité de permettre à l'utilisateur de choisir un fuseau horaire pour l'événement (différent de leur réglage régional) qu'ils ajoutent et d'ajouter les informations à SharePoint de telle sorte qu'il affichera la bonne heure pour chaque utilisateur en regardant le monde ( basé sur leur cadre régional bien sûr). J'ai ajouté une liste à SharePoint qui est utilisée pour rechercher SystemTezones (essentiellement une liste de liste SharePoint de TimezoneInfo.GetsystemTzones ())

                SPList timeZonesList = thisWeb.Lists.TryGetList("SystemTimeZones");

                if(timeZonesList == null)
                {
                    string title = "SystemTimeZones";
                    string description = "SharePoint List representation of TimeZoneInfo.GetSystemTimeZones() used for lookup.";

                    Guid newListId = thisWeb.Lists.Add(title, description, SPListTemplateType.GenericList);

                    timeZonesList = thisWeb.Lists.GetList(newListId, true);
                    timeZonesList.Fields.Add("SystemTimeZoneId", SPFieldType.Text, true);
                    timeZonesList.Fields.Add("SystemTimeZoneName", SPFieldType.Text, true);

                    SPView defaultTimeZonesView = timeZonesList.DefaultView;
                    defaultTimeZonesView.ViewFields.Add("SystemTimeZoneId");
                    defaultTimeZonesView.ViewFields.Add("SystemTimeZoneName");
                    defaultTimeZonesView.Update();

                    foreach (TimeZoneInfo timeZone in TimeZoneInfo.GetSystemTimeZones())
                    {
                        SPListItem temp = timeZonesList.AddItem();
                        temp["SystemTimeZoneId"] = timeZone.Id;
                        temp["SystemTimeZoneName"] = timeZone.DisplayName;
                        temp.Update();
                    }
                } 

J'utilise cette liste pour l'élément de recherche pour EventTimezone dans mes formulaires d'addition personnalisés et d'édition pour cette liste. Les formulaires sont des copies directes de ce que SharePoint Designer créerait (en ce sens qu'elles utilisent le SharePoint: Formfield's) Ils sont juste dans Visual Studio BC, j'avais besoin du code de code. Je voulais permettre aux utilisateurs de voir les événements dans leur fuseau horaire régional quand ils les éditer, je voulais leur montrer dans le fuseau horaire entré. (C'est-à-dire que mon fuseau horaire régional est au centre de la qualité, alors quand je regarde une rencontre de montagne, cela me montrera 10-11 heures, mais quand je modifierai la même réunion, il dira qu'il est de 9 à 10h). Donc, sur la charge de la page de modification, je ajuste les temps:

                        SPListItem thisEvent = eventsList.GetItemById(savebutton1.ItemId);

                        if (thisEvent != null)
                        {
                            bool isAllDayEvent = false;
                            if (thisEvent["fAllDayEvent"] != null)
                            {
                                isAllDayEvent = (bool)thisEvent["fAllDayEvent"];
                            }

                            if (!isAllDayEvent)
                            {
                                SPFieldLookupValue lookupValue = new SPFieldLookupValue(thisEvent["Event Time Zone"].ToString());
                                TimeZoneInfo eventTimeZone = GetEventTimeZoneByListItemId(lookupValue.LookupId, rootWeb);
                                SPTimeZone regionalTimeZone = GetRegionalTimeZone(rootWeb);

                                DateTime regionalStartDateTime = Convert.ToDateTime(thisEvent["StartDate"]);
                                DateTime originalStartDateTime = TimeZoneInfo.ConvertTimeFromUtc(regionalTimeZone.LocalTimeToUTC(regionalStartDateTime), eventTimeZone);

                                ff3.ListItemFieldValue = originalStartDateTime;

                                DateTime regionalEndDateTime = Convert.ToDateTime(thisEvent["EndDate"]);
                                DateTime originalEndDateTime = TimeZoneInfo.ConvertTimeFromUtc(regionalTimeZone.LocalTimeToUTC(regionalEndDateTime), eventTimeZone);

                                ff4.ListItemFieldValue = originalEndDateTime;
                            }
                            else
                            {
                                // for some reason with all day events, sharepoint saves them 
                                // as the previous day 6pm. but when they show up to any user
                                // they will show as 12am to 1159pm and show up correctly on the calendar
                                // HOWEVER, when it comes to edit, the start date isn't corrected on the 
                                // form, so continuing to save without fixing it will continue to decrease
                                // the start date/time by one day
                                DateTime regionalStartDateTime = Convert.ToDateTime(thisEvent["StartDate"]);
                                ff3.ListItemFieldValue = regionalStartDateTime.AddDays(1);
                            } 

Les événements de toute la journée étaient étranges mais j'ai pu le faire fonctionner en écrivant simplement des cas de test et voir ce qui s'est passé (comme vous pouvez le voir de mes commentaires).

Puis je noue dans les récepteurs de récepteurs de récepteurs de récepteurs d'événements de liste et dans l'optionDached sur "Correction" des temps écoulés depuis que SharePoint va les enregistrer en fonction du réglage régional de l'utilisateur et non du fuseau horaire que l'utilisateur a choisi. (Bien sûr, je suis légèrement nouveau à SharePoint - pas C # - J'ai donc pu avoir beaucoup compliqué cela, mais j'ai pu amener une petite documentation en ligne en ligne). En fin de compte, je finis par définir:

                    addedItem["StartDate"] = regionalTimeZone.UTCToLocalTime(correctedEventStart.ToUniversalTime());
                    addedItem["EndDate"] = regionalTimeZone.UTCToLocalTime(correctedEventEnd.ToUniversalTime()); TADA!! It saves and display perfectly! I was so excited! Until... I tried to save a recurring event. All of my recurring events save wonderfully, it's not the recurring part that's messed up. For some reason, after I change the StartDate and EndDate on a recurring event and call addedItem.Update() it is recalculating the "Duration" as if it is a single even instead of a recurring event.  Example: I have an event that happens for a week daily from 9-10.  When I first enter ItemAdded my Duration is 3600 (1 hour) as it should be bc Duration is treated differently for recurring events. However after I adjust the times and call Update() the duration spans the entire week :( If I manually set the Duration:
                     if (isRecurrence)
                    {
                        addedItem["Duration"] = (correctedEventEnd.TimeOfDay - correctedEventStart.TimeOfDay).TotalSeconds;
                    }  

Il est toujours réinitialisé sur la mise à jour (). Ainsi, lorsque vous affichez l'article récurrent d'une vue de calendrier, l'article couvre toute la semaine au lieu de montrer une fois par jour.

J'ai tous sauté mes cheveux en essayant de comprendre cela. Toute directive serait merveilleuse. Je comprends la durée est un champ calculé, mais je ne comprends pas pourquoi appeler LisTem.Update () ignorerait le fait qu'il est bien marqué comme un événement récurrent et non de calculer la durée correctement. Cela semble honnêtement comme un bug avec SP 2010.

Merci d'avance!

Était-ce utile?

La solution

OK, la façon dont j'ai fini par manipuler cela est comme suit.J'ai décidé de revenir hors du récepteur d'événement de liste car il semble vraiment être un bogue SharePoint dans la recalcul de la durée des événements récurrents fonctionnant maintenant correctement.J'ai choisi de lier dans l'événement Sauvegarder sur le formulaire et de modifier les valeurs avant qu'ils ne soient même envoyés.Cela semble fonctionner jusqu'à présent dans tous les scénarios.Toutes mes mathématiques sont les mêmes qu'auparavant.Donc, dans mon nouveau 2.aspx (nouveau formulaire d'élément pour cette liste)

protected override void OnInit(EventArgs e)
{
    base.OnInit(e);

    if ((SPContext.Current.FormContext.FormMode == SPControlMode.New) || (SPContext.Current.FormContext.FormMode == SPControlMode.Edit))
    {
        SPContext.Current.FormContext.OnSaveHandler += new EventHandler(SaveHandler);
    }
}

protected void SaveHandler(object sender, EventArgs e)
{
    Page.Validate();

    if (Page.IsValid)
    {
        // fix times
        SPFieldLookupValue lookupValue = new SPFieldLookupValue(ff5.Value.ToString());
        TimeZoneInfo eventTimeZone = GetEventTimeZoneByListItemId(lookupValue.LookupId, SPContext.Current.Web);
        SPTimeZone regionalTimeZone = GetRegionalTimeZone(SPContext.Current.Web);

        bool isAllDayEvent = Convert.ToBoolean(ff6.Value);
        bool isRecurrence = Convert.ToBoolean(ff11.Value);
        DateTime correctedEventStart = DateTime.MinValue;
        DateTime correctedEventEnd = DateTime.MinValue;

        if (!isAllDayEvent && eventTimeZone != null && regionalTimeZone != null)
        {
            correctedEventStart = DateTime.Parse(ff3.Value.ToString() + " " + eventTimeZone.GetUtcOffset(DateTime.UtcNow).Hours + ":" + eventTimeZone.GetUtcOffset(DateTime.UtcNow).Minutes);
            correctedEventEnd = DateTime.Parse(ff4.Value.ToString() + " " + eventTimeZone.GetUtcOffset(DateTime.UtcNow).Hours + ":" + eventTimeZone.GetUtcOffset(DateTime.UtcNow).Minutes);

            ff3.ItemFieldValue = regionalTimeZone.UTCToLocalTime(correctedEventStart.ToUniversalTime());
            ff4.ItemFieldValue = regionalTimeZone.UTCToLocalTime(correctedEventEnd.ToUniversalTime());
        }

        SPContext.Current.ListItem.Update();
    }
}

Ceci met à jour les temps comme mon approche précédente, mais cela calculera également la durée correctement.

Poignées SharePoint Affichage de l'heure correcte en fonction des paramètres régionaux de l'utilisateur (ou Web si l'utilisateur n'a pas défini) et affichant les heures corrigentes des vues de calendrier.J'ai dû changer le formulaire d'édition pour avoir les valeurs correctes sur Modifier:

protected void Page_Load(object sender, EventArgs e)
    {
        if (!Page.IsPostBack)
        {
            try
            {
                using (SPWeb rootWeb = SPContext.Current.Site.RootWeb)
                {
                    SPList eventsList = rootWeb.Lists.TryGetList("Events");

                    if (eventsList != null)
                    {
                        SPListItem thisEvent = eventsList.GetItemById(savebutton1.ItemId);

                        if (thisEvent != null)
                        {
                            bool isAllDayEvent = false;
                            if (thisEvent["fAllDayEvent"] != null)
                            {
                                isAllDayEvent = (bool)thisEvent["fAllDayEvent"];
                            }

                            if (!isAllDayEvent)
                            {
                                SPFieldLookupValue lookupValue = new SPFieldLookupValue(thisEvent["Event Time Zone"].ToString());
                                TimeZoneInfo eventTimeZone = GetEventTimeZoneByListItemId(lookupValue.LookupId, rootWeb);
                                SPTimeZone regionalTimeZone = GetRegionalTimeZone(rootWeb);

                                DateTime regionalStartDateTime = Convert.ToDateTime(thisEvent["StartDate"]);
                                DateTime originalStartDateTime = TimeZoneInfo.ConvertTimeFromUtc(regionalTimeZone.LocalTimeToUTC(regionalStartDateTime), eventTimeZone);

                                ff3.ListItemFieldValue = originalStartDateTime;

                                DateTime regionalEndDateTime = Convert.ToDateTime(thisEvent["EndDate"]);
                                DateTime originalEndDateTime = TimeZoneInfo.ConvertTimeFromUtc(regionalTimeZone.LocalTimeToUTC(regionalEndDateTime), eventTimeZone);

                                ff4.ListItemFieldValue = originalEndDateTime;
                            }
                            else
                            {
                                // for some reason with all day events, sharepoint saves them
                                // as the previous day 6pm. but when they show up to any user
                                // they will show as 12am to 1159pm and show up correctly on the calendar
                                // HOWEVER, when it comes to edit, the start date isn't corrected on the
                                // form, so continuing to save without fixing it will continue to decrease
                                // the start date/time by one day
                                DateTime regionalStartDateTime = Convert.ToDateTime(thisEvent["StartDate"]);
                                ff3.ListItemFieldValue = regionalStartDateTime.AddDays(1);
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                DebugLogger.WriteLine(ex);
            }
        }
    }

Le formulaire d'édition a le même oninit et sauvegardier comme neuf.

Licencié sous: CC-BY-SA avec attribution
Non affilié à sharepoint.stackexchange
scroll top