10814 : I want to change the cursor while resizing the time item and while moving the time item?

Question

I want to change the cursor while resizing the time item and while moving the time item, how is it possible ?

Answer

You can implement the OnPreCursorChangeEvent on Gantt.TimeItemArea

You can check the Gantt.MouseMoveKind to get information about ongoing operations.

You can also look at this article https://plexityhide.com/faqs_gen_GTPNET/10547.htm

10789 : Is there any way to cancel a drag and of a TimeItem (GTP.net version) once the drag is underway?

Question

Is there any way to cancel a drag and drop of a TimeItem (GTP.net version) once the drag is underway? I believe the COM version could do this by hitting Esc or clicking the other mouse button. Thanks.

Answer

For the end user there is currently no way to cancel an ongoing drag. For the developer you can call Gantt.MouseMoveCancel() so you can implement an ESC key of your own as a work around.

 

10930 : Has the behaviour of e.Allow changed in the TimeItem_AfterMove event?

Question

Has the behaviour of e.Allow changed in the TimeItem_AfterMove event? Using GTP V3.0.6.17 and e.Allow seems to always be set to False in this event despite it being set to True at (say) the end of the TimeItem_Move event. Many thanks.

 

Answer

 

I do not think that it has changed.< ?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

The OnTimeItem_AfterMove does not check the Allow flag in the current versions or earlier. The move is already done… We do however check the allow flag in the following events:

OnTimeItem_BeforeMove,

OnTimeItem_Hoover,

OnTimeItem_AfterCreateByMouse,

OnTimeItem_StartChange,

OnTimeItem_StopChange,

OnTimeItem_Move,

OnTimeItem_ChangeRow,

OnTimeItem_LinkCreate,

OnTimeItem_StartValueResize,

OnTimeItem_StopValueResize

 

10780 : In print preview images from imageList are not where they should be?

Question

I have question about custom cells draw and print preview< ?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

 

This is my source:

 

private void gantt_OnGridCustomCellDraw(PlexityHide.GTP.Grid aGrid, PlexityHide.GTP.CustomCellEventArgs e)

{

    int width = Math.Min(e.Cell.CellRect.Width, imageList.ImageSize.Width);

    int height = Math.Min(e.Cell.CellRect.Height, imageList.ImageSize.Width);

    int size = Math.Min(width, height);

    int x = e.Cell.CellRect.Left + Math.Max(0, (e.Cell.CellRect.Width – size) / 2);

    int y = e.Cell.CellRect.Top + Math.Max(0, (e.Cell.CellRect.Height – size) / 2);

    e.G.DrawImage(pictureBox1.Image, x, y, size, size);

    imageList.Draw(e.G, x, y, size, size, 1);

}

 

It draw perfect my custom cell images.

 

But in print preview images from imageList are not where they have to be. Image from pictureBox1 is on the right place.

 

Why is that? What approach I have to use when I want to draw more different images?

 

Answer

 

In the print your cell is scaled depending on the device context. Your printer likely has greater resolution than your screen. All this is handled by the Graphics object.

 

BUT the imageList.Draw somehow neglects to see this (I would say it is an image list bug).

 

To workaround go like this: 

e.G.DrawImage(imageList.Images[1],x,y);

 

instead of like this:

BUG    imageList.Draw(e.G, x, y, size, size, 1);

 

10926 : When hosting ASP.NET Ajax applications in a frame or iframe I get “access denied”

Question

 When hosting ASP.NET Ajax applications in a frame or iframe that’s in a different domain from the top-level window. If you try to do that and browse to the page using IE, you’ll receive an “access denied” error client-side  issue with < ?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" />Ajax 1.0< ?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

Do you have any solutions for this?  I am calling my web app from within salesforce.com page and it doesn’t work.

Answer

There is a very good description and solution here, and I quote the important part of text just in case it goes offline:

How to work around the access denied cross-domain frame issue in ASP.NET Ajax 1.0

Some users have run into an issue when hosting ASP.NET Ajax applications in a frame or iframe that’s in a different domain from the top-level window. If you try to do that and browse to the page using IE, you’ll receive an “access denied” error client-side any time a DOM event is raised in the frame. The code that’s responsible for that is Sys.UI.getLocation. This is a tricky piece of code that determines the pixel coordinates of a DOM element relative to the top-left corner of the page, so that an absolutely positioned child of the body using these coordinates would exactly cover the element you measured. This is useful for drag & drop, popup scenarios like auto-complete and when an event is raised to get mouse coordinates relative to the event source. This is this last piece that explains the problem. The code in this method is different for each of the browsers that we support because each one of them has its own behavior that cannot be determined as we usually do by dynamically looking at capabilities. You just have to know for example that browser X is not counting an element’s scroll position if it’s absolutely positioned and a direct child of body (names changed to protect the guilty). That’s the kind of problem we had to work around. Luckily, IE has two very handy methods to retrieve this kind of coordinates that enables us to bypass completely a number of bugs that we just couldn’t efficiently work around: getClientRects, which gets all rectangles the element occupies on the page, and getBoundingClientRect, which returns a single rectangle that bounds the whole element. In the method that we shipped, we’ve been using getClientRects and getting the first rectangle because we wanted to have consistent behavior across browsers even if the element is a wrapping element such as a span: in this case, the top-left corner of the element is the top-left corner of the first bounding rectangle, which is different from the top-left corner of the global bounding rectangle:

 

And this is where we made a mistake, unfortunately too late. There is a subtle difference between getClientRects and getBoundingClientRect, which is that getClientRects, when in an iframe, gives coordinates that include the offset of that frame in the top window, whereas getBoundingClientRect gives the right coordinates directly. Both need to include the frameborder to be perfectly accurate. To correct the behavior of getClientRects, we had to look at the coordinates of the frame relative to the top window, to subtract them, and this is the operation that is not allowed if the frames are in different domains.

The fix is to use getBoundingClientRect instead, which will introduce a small inconsistency across browsers in the case of wrapping elements but is a lot better than just failing. The new version of the function still needs to try/catch around the code that fixes the frameborder, so for cross-domain frames you may get a 2 pixel offset in the coordinates but this is the best you can get.

How to apply the fix

First, you’ll need to use the external script files instead of the resource-based ones. You do this by setting a general ScriptPath on the ScriptManager. The external script files can be found in the Microsoft Ajax Library (http://ajax.asp.net/downloads/library/default.aspx?tabid=47&subtabid=471) which is under the MSPL (which allows you to modify the files). Copy the System.Web.Extensions folder found in the Library zip into the folder you pointed ScriptPath to.

Alternatively, if you don’t want to have all your script references path-based, you can point only the core framework to a file and leave the others to use web resources as usual. This makes things easier when using other resource-based libraries such as the toolkit. This is easily done by adding the following script reference to your script manager:

<asp:ScriptReference
    Name=”MicrosoftAjax.js” ScriptMode=”Auto”
   
Path=”~/[Your Script Directory]/System.Web.Extensions/1.0.61025.0/MicrosoftAjax.js”

/>

Of course, don’t forget to replace the part of the path between the brackets with the name of the script directory you chose. Don’t set a ScriptPath on the script manager if you choose to use this script reference. 

Once you’ve done that, you can check that the application still works and loads the script from the new location using a network monitoring tool such as Fiddler.

The second step is to patch the files. You’ll need to patch the debug and release versions.

The debug version is MicrosoftAjax.debug.js. Look for the following code:

switch(Sys.Browser.agent) {
    case Sys.Browser.InternetExplorer:

then replace everything between that and “case Sys.Browser.Safari:” with the following code:

Sys.UI.DomElement.getLocation = function(element) {
    if (element.self || element.nodeType === 9) return new Sys.UI.Point(0,0);
    var clientRect = element.getBoundingClientRect();
    if (!clientRect) {
        return new Sys.UI.Point(0,0);
    }
    var ownerDocument = element.document.documentElement;
    var offsetX = clientRect.left - 2 + ownerDocument.scrollLeft,
        offsetY = clientRect.top - 2 + ownerDocument.scrollTop;
    
    try {
        var f = element.ownerDocument.parentWindow.frameElement || null;
        if (f) {
            var offset = 2 - (f.frameBorder || 1) * 2;
            offsetX += offset;
            offsetY += offset;
        }
    }
    catch(ex) {
    }    
    
    return new Sys.UI.Point(offsetX, offsetY);
}
break;

For the release version (MicrosoftAjax.js), the process is pretty much the same except that the file is a little more difficult to manipulate. Look for “switch(Sys.Browser.agent){case Sys.Browser.InternetExplorer:” and replace everything between that and “case Sys.Browser.Safari:” with the following:

Sys.UI.DomElement.getLocation=function(a){if(a.self||a.nodeType===9)return new Sys.UI.Point(0,0);var b=a.getBoundingClientRect();if(!b)return new Sys.UI.Point(0,0);var c=a.document.documentElement,d=b.left-2+c.scrollLeft,e=b.top-2+c.scrollTop;try{var g=a.ownerDocument.parentWindow.frameElement||null;if(g){var f=2-(g.frameBorder||1)*2;d+=f;e+=f}}catch(h){}return new Sys.UI.Point(d,e)};break;

(no line breaks)

The site should now work without the exceptions.

10891 : Is there any example available showing the use of a pure AJAX controlled Gantt, i.e. not just the wrapped one?

Question

Is there any example available showing the use of a pure AJAX controlled  Gantt, i.e. not just the wrapped one?

 

< ?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />Answer

 

In the download we only have Ajax samples wrapping the windows forms component(currently). The main reason for this is that when wrapping a windows forms Gantt you get access to the design time properties and that is practical. If you do not want the form in there you can always copy the designer-auto-generated-code to the webform or a class file.

 

10778 : The TimeItemTexts array?

Question

The TimeItemTexts are an array connected to the TimeItem and that seems great to store different texts to these Items and show them on occation. But how do I tell the timeitems what item of TimeItemTexts they shall display? Can I set the index to display in some property?

 

Answer< ?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

The reason for having a collection of TimeItemTexts per TimeItem is to facilitate multiple shown parts of information (text or image) in or around each time item.

You can control the placement of the time item texts by setting the TimeItemTextLayout properties. So Align in horizontal and vertical to control any of 3×3 possible placements. 

Also the “Outside” property of the TimeItemTextLayout gives you 3×3 more placements outside but near your time item.

It will not make much sense to keep multiple TimeItemTexts on a single time item if they have the same TimeItemTextLayout (unless we introduce a visible property or the like).

10885 : I have placed the horizontal scroll bar on the TimeItemArea and i want to scroll the TimeItemArea from the scroll bar.

Question

I have placed the horizontal scroll bar on the TimeItemArea and i want to scroll the TimeItemArea from the scroll bar. How’s this possible ??

Answer

Drop a HScrollBar and a Gantt to your form, then implement these events:

    private void Form1_Load(object sender, EventArgs e)
    {
      gantt1.DateScaler.LowerBound=DateTime.Today.AddDays(-365);
      gantt1.DateScaler.UpperBound = DateTime.Today.AddDays(+365);
      gantt1.DateScaler.TimeSpanSet(DateTime.Today, DateTime.Today.AddDays(30));

      // Add a scrollbar to timeitemarea

      hScrollBar1.Parent=gantt1.TimeItemArea;
      hScrollBar1.Dock=DockStyle.Bottom;
      hScrollBar1.Maximum=1000;
      hScrollBar1.Minimum=0;
           
    }

    private void gantt1_OnDateScalerScaleChangeEvent(object sender, EventArgs e)
    {
      // Update the scrollbar whenever the DateScaler change
      
      TimeSpan ts1=gantt1.DateScaler.UpperBound.Subtract(gantt1.DateScaler.LowerBound);
      TimeSpan ts2 = gantt1.DateScaler.StartTime.Subtract(gantt1.DateScaler.LowerBound);
      TimeSpan ts3 = gantt1.DateScaler.StopTime.Subtract(gantt1.DateScaler.StartTime);    

      hScrollBar1.Value = (int)(hScrollBar1.Maximum * ts2.Ticks / ts1.Ticks);
      hScrollBar1.LargeChange=(int)(hScrollBar1.Maximum * ts3.Ticks/ts1.Ticks);
    }

    private void hScrollBar1_Scroll(object sender, ScrollEventArgs e)
    {
      // Update the DateScaler whenever the scrollbar change…
     
      TimeSpan ts1=gantt1.DateScaler.UpperBound.Subtract(gantt1.DateScaler.LowerBound);
      TimeSpan ts2 = new TimeSpan(hScrollBar1.Value * ts1.Ticks / hScrollBar1.Maximum);
      TimeSpan ts3 = gantt1.DateScaler.StopTime.Subtract(gantt1.DateScaler.StartTime);
      gantt1.DateScaler.TimeSpanSet(gantt1.DateScaler.LowerBound.Add(ts2),gantt1.DateScaler.LowerBound.Add(ts2).Add(ts3));
    }

10834 : How can i get the Row-Number on gantt1_OnTimeItem_ChangeRow?

< ?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />Question

How can i get the Row-Number on gantt1_OnTimeItem_ChangeRow?

 

Answer

For the old row you follow e.TimeItem.GanttRow.GridNode.Index

For the new row you follow e.NewGanttRow.GridNode.Index

Mind you that the Index is the Index of the list of GridNodes (Grid.OwningCollection), if this node is a sub node you will get the index of the position within that child list.