locked
Getting a application wide scrollbar and disabling listView scrollbar

    Question

  • Hello All

    I'm trying to get a horizontal scrollbar to show up in my containing div and for the div which contains my listView to not show it's scrollbar.

    The basic structure of my project is as follows:

        <div id="containerDiv" >
            <div id="accountsPageControl"
                 data-win-control="WinJS.UI.HtmlControl"
                 data-win-options="{ uri: '/pages/accountsPageControl/accountsPageControl.html'}">
             </div>
            <div id="categoriesPageControl" 
                 data-win-control="WinJS.UI.HtmlControl"
                 data-win-options="{uri: '/pages/categoriesView/categoriesView.html' }">
            </div>
        </div>

    categoriesPageControl contains a listview which has a scrollbar. I'd like that listView to not show it's scrollbar and rather that containerDiv shows a scrollbar which moves accountsPageControl and categoriesPageControl.

    The way I approached this is to set the width of the containing div categoriesPageControl to whatever width it needs to be(in this case say 3000px) which would be the width of accountsPageControl plus the width of the listView in categoriesPageControl.

    The problem is that I don't know what width listView is going to have, since it's dynamic it can really have any width. I was hoping that the listView would have some events like "dataLoaded or layoutComplete" or something which I could hook into to update the width of my containing div with javascript. However I can't see anything in the documentation concerning data or layout events for the listView.

    So one way I could approach this situation would be to add an eventlistener the listView's layout class but when I tried that:

                var listView = document.body.querySelector("#categoryView").winControl;
                listView.layout.addEventListener("endLayout", function (eventInfo) {
                    var mydiv = document.body.querySelector("#categoryView");
                    console.log('I have loaded my data my width is' + listView.element.style.width);
                });

    I get told that Object doesn't support property or method 'addEventListener'

    So is there a way to listen for GridLayout events. Or perhaps there's a much better way to do what I'm trying to achieve?


    • Edited by Syllogism Monday, August 27, 2012 3:31 PM spelling
    Monday, August 27, 2012 3:28 PM

Answers

All replies

  • Would onloadingstate meet your needs? http://msdn.microsoft.com/en-us/library/windows/apps/Hh700709.aspx

    -Jeff


    Jeff Sanders (MSFT)

    • Marked as answer by Dino He Monday, September 24, 2012 3:12 AM
    Monday, August 27, 2012 5:47 PM
    Moderator
  • thanks, this does the trick
    Tuesday, September 25, 2012 10:03 AM
  • You shouldn't have to do anything fancy with the events.  You can wrap the categoriesPageControl in another div with the style overflow-x: scroll and overflow-y:hidden and it should work. The default style for .win-listview in the built-in styles (ui-light, ui-dark) has overflow: hidden set, so you may have to override that in your page CSS.  Depends a bit on the layout.  You definitely have to play with it a bit, but it's totally doable in CSS. We have the same scrolling (container, not listview) in all our pages and there is a certain amount of variety in the amount of data in the listview and other layout elements on the page.  We got it working in every case without resorting to handling the listview events.
    Tuesday, September 25, 2012 1:32 PM
  • well in the end I didn't get too complicated but I'm still using an event. I just grab the canvaslength of the listview and set the containing div to that width using jQuery to overwrite the style. Of course if there's a way to do it without coding that would be ideal.

    in my pagecontrol ready handler I have the following code:

     var listView = element.querySelector("#categoryView").winControl;
                listView.addEventListener("loadingstatechanged", function (eventInfo) {
                    $('#monthlyListView').css('width', listView._canvasLength + 100);
    
                });

    here's my basic structure:

    <body>
        <div id="container" >
    		<div id="title">22seven</div>
    		<div id="moneyInOut">money In Money Out</div>
    		<div id="hob">hob</div>
    		<div id="monthViews">
    			<div id="monthlyTrxns" >monthlyTrxns asd asd </div>
    
                <div id="monthlyListView"
                    data-win-control="WinJS.UI.HtmlControl"
                    data-win-options="{uri: '/pages/pagecontrol.html' }">
                </div>
    
    		</div>
    		
    	</div>
    </body>

    and my css:

    #container {
    	height:100%;
    	display: -ms-grid;
    	-ms-grid-columns: 100px 560px 1fr;
    	-ms-grid-rows: 100px 30fr 37fr;
        overflow-y:hidden;
    }
    
    #title{
    	-ms-grid-row: 1;
    	-ms-grid-column: 2;
    	-ms-grid-row-align: end;
    }
    
    #moneyInOut{
    	-ms-grid-column: 2;
    	-ms-grid-row: 2;
    	-ms-grid-row-align: center;
    	-ms-grid-column-align: center;
    }
    
    #hob{
    	-ms-grid-row: 3;
    	-ms-grid-column: 2;
    	-ms-grid-row-align: center;
    	-ms-grid-column-align: center;
    }
    
    #monthViews{
    	-ms-grid-column: 3;
    	background-color: #BD1F1F;
    	-ms-grid-row-span: 3;
    	display: -ms-grid;
    	-ms-grid-rows: 260px 1fr;
    }
    
    #monthlyTrxns{
    	-ms-grid-row: 1;
    }
    
    #monthlyListView{
    	-ms-grid-row: 2;
    	/* width:7200px; */
         overflow:hidden;
         height:100%
    }
    
    .win-listview > .win-horizontal.win-viewport {
       overflow-x: hidden;
       overflow-y: hidden;
    }
    
    .win-listview {
       height: 80%;
       overflow: hidden;
    }

    Tuesday, September 25, 2012 1:54 PM
  • I think the main thing we found is you often need an additional div inside your main container that can provide the scrolling.  For some reason overflow settings on the main container div don't seem to do the trick, at least not in a lot of cases.
    Tuesday, September 25, 2012 1:57 PM
  • I've been struggling with this same issue. I first tried to use skills0's suggestions and was able to override the scrolling by setting overflow: visible on the win-listview and win-viewport classes. (I did need to use overflow, not just overflow-x, and I needed the !important flag on the win-viewport style for it to actually take precedence over ui-light.css.) Superficially this looked right, but it apparently confused the listview's scroll listeners, so that new pages of items loaded much too slowly or not at all as you scrolled through the list.

    Ultimately I wanted something that looked like the Windows app store, where the list view only takes up part of the page but controls the scrollbar for the entire page, instead of getting its own scrollbar. So I tried the approach at social.msdn.microsoft.com/Forums/en-US/winappswithhtml5/thread/5d11c2ac-c6ab-4160-bbdf-3e222c2a6b3a. My list view started 186px from the top of the page, so I set the height to 100vh-186px and set overflow:visible on the win-listview:

    .win-viewport {
        padding-left: 100px;
        height: calc(100vh - 186px);
    }
    
    .win-listview {
        overflow: visible;
    }

    (The padding was so the list-view would be offset from the end of the page, but would run all the way off the end of the page once you start scrolling - again, like the app store.)

    This puts the listview's scrollbar where the full-page scrollbar would normally be. It's hacky, but it works. You might need to set overflow on a containing element to ensure that the full-page scrollbar doesn't also show up, as it'll appear on top of the listview's scrollbar.

    Just thought I'd share in case anyone else struggles with this as much as I did :)

    Monday, December 03, 2012 5:45 PM