Handling Orientation in Windows 8.1 Store app -
i making win store app, , facing issue handle orientation.
there grid, want modify design of when orientation changed. stack panels in both sides (in landscape view) should goto top , bottom in portrait view.
currently have created 2 grids controls , adjust them according orientation, , switching visibility property, using visualstatemanager.
but want achieve single grid, suggestion great me.
the below image concept design of app: 
doing single grid difficult, possible.
firstly, want worry less orientation , more horizontal width. way, if user snaps app in such way there isn't horizontal space (similar portrait mode), can display similar experience.
now, onto grid.
the key here moving grid with, in essence, 3 columns 1 one column. such, need modify columnspan property of cells.
what have drawn far has 3 columns, each width of gridlength *. start there.
<grid> <grid.columndefinitions> <columndefinition width="*"/> <columndefinition width="*"/> <columndefinition width="*"/> </grid.columndefinitions> </grid> next, want set rows. it's better make number of rows largest you'll need, count 6. if set them auto, empty rows (in landscape orientation) disappear.
<grid> <grid.columndefinitions> <columndefinition width="*"/> <columndefinition width="*"/> <columndefinition width="*"/> </grid.columndefinitions> <grid.rowdefinitions> <rowdefinition width="auto"/> <rowdefinition width="auto"/> <rowdefinition width="auto"/> <rowdefinition width="auto"/> <rowdefinition width="auto"/> <rowdefinition width="auto"/> </grid.columndefinitions> </grid> now, create basic contents. i'm going create bunch of different stackpanels , name them have contained in them.
i setting default grid/row values of landscape. using 2 rows 'second row' (containing stackpanels 1 , 2). both stackpanels have rowspan of 2 compensate.
<grid> <grid.columndefinitions> <columndefinition width="*"/> <columndefinition width="*"/> <columndefinition width="*"/> </grid.columndefinitions> <grid.rowdefinitions> <rowdefinition width="auto"/> <rowdefinition width="auto"/> <rowdefinition width="auto"/> <rowdefinition width="auto"/> <rowdefinition width="auto"/> <rowdefinition width="auto"/> </grid.columndefinitions> <stackpanel name="headerrow" grid.row="0" grid.column="0" grid.columnspan="3"/> <stackpanel name="stackpanel1" grid.row="1" grid.column="0" grid.rowspan="2"/> <stackpanel name="content" grid.row="1" grid.column="1"/> <stackpanel name="bluesection" grid.row="2" grid.column="1"/> <stackpanel name="stackpanel2" grid.row="1" grid.column="2" grid.rowspan="2"/> <stackpanel name="footerrow" grid.row="3" grid.column="0" grid.columnspan="3"/> </grid> now have nice definition landscape orientation. automatically size vertically based on content within well, though free whatever minimum sizing want.
now we've done this, need create visualstates our different sizes. in 1 visualstate defining we've done. in other, creating new one. naming them 'landscape' , 'portrait' now, suggest doing 'mid' , 'wide', , defining used based on bounds given. have omitted previous definitions sake of space.
technically, don't need include landscape definition, i'm including additional example.
note: in second picture, have stackpanel2 below footer. have reflected below. if need changed, change row definitions of stackpanel2 4 , of footer 5.
<grid> ... <visualstatemanager.visualstategroups> <visualstategroup x:name="orientationstates"> <!-- we've defined --> <visualstate x:name="landscape"> <objectanimationusingkeyframes storyboard.targetproperty="(grid.rowspan)" storyboard.targetname="stackpanel1"> <discreteobjectkeyframe keytime="0" value="2"/> </objectanimationusingkeyframes> <objectanimationusingkeyframes storyboard.targetproperty="(grid.columnspan)" storyboard.targetname="stackpanel1"> <discreteobjectkeyframe keytime="0" value="1"/> </objectanimationusingkeyframes> <!-- stack panel 2 --> <objectanimationusingkeyframes storyboard.targetproperty="(grid.rowspan)" storyboard.targetname="stackpanel2"> <discreteobjectkeyframe keytime="0" value="2"/> </objectanimationusingkeyframes> <objectanimationusingkeyframes storyboard.targetproperty="(grid.columnspan)" storyboard.targetname="stackpanel2"> <discreteobjectkeyframe keytime="0" value="1"/> </objectanimationusingkeyframes> <objectanimationusingkeyframes storyboard.targetproperty="(grid.row)" storyboard.targetname="stackpanel2"> <discreteobjectkeyframe keytime="0" value="1"/> </objectanimationusingkeyframes> <objectanimationusingkeyframes storyboard.targetproperty="(grid.column)" storyboard.targetname="stackpanel2"> <discreteobjectkeyframe keytime="0" value="2"/> </objectanimationusingkeyframes> <!-- content --> <objectanimationusingkeyframes storyboard.targetproperty="(grid.row)" storyboard.targetname="content"> <discreteobjectkeyframe keytime="0" value="1"/> </objectanimationusingkeyframes> <objectanimationusingkeyframes storyboard.targetproperty="(grid.column)" storyboard.targetname="content"> <discreteobjectkeyframe keytime="0" value="1"/> </objectanimationusingkeyframes> <objectanimationusingkeyframes storyboard.targetproperty="(grid.columnspan)" storyboard.targetname="content"> <discreteobjectkeyframe keytime="0" value="1"/> </objectanimationusingkeyframes> <! -- blue section --> <objectanimationusingkeyframes storyboard.targetproperty="(grid.row)" storyboard.targetname="bluesection"> <discreteobjectkeyframe keytime="0" value="2"/> </objectanimationusingkeyframes> <objectanimationusingkeyframes storyboard.targetproperty="(grid.column)" storyboard.targetname="bluesection"> <discreteobjectkeyframe keytime="0" value="1"/> </objectanimationusingkeyframes> <objectanimationusingkeyframes storyboard.targetproperty="(grid.columnspan)" storyboard.targetname="bluesection"> <discreteobjectkeyframe keytime="0" value="1"/> </objectanimationusingkeyframes> <!-- footer --> <objectanimationusingkeyframes storyboard.targetproperty="(grid.row)" storyboard.targetname="footer"> <discreteobjectkeyframe keytime="0" value="3"/> </objectanimationusingkeyframes> </visualstate> <!-- new section --> <visualstate x:name="portrait"> <objectanimationusingkeyframes storyboard.targetproperty="(grid.rowspan)" storyboard.targetname="stackpanel1"> <discreteobjectkeyframe keytime="0" value="1"/> </objectanimationusingkeyframes> <objectanimationusingkeyframes storyboard.targetproperty="(grid.columnspan)" storyboard.targetname="stackpanel1"> <discreteobjectkeyframe keytime="0" value="3"/> </objectanimationusingkeyframes> <!-- stack panel 2 --> <objectanimationusingkeyframes storyboard.targetproperty="(grid.rowspan)" storyboard.targetname="stackpanel2"> <discreteobjectkeyframe keytime="0" value="1"/> </objectanimationusingkeyframes> <objectanimationusingkeyframes storyboard.targetproperty="(grid.columnspan)" storyboard.targetname="stackpanel2"> <discreteobjectkeyframe keytime="0" value="3"/> </objectanimationusingkeyframes> <objectanimationusingkeyframes storyboard.targetproperty="(grid.row)" storyboard.targetname="stackpanel2"> <discreteobjectkeyframe keytime="0" value="5"/> </objectanimationusingkeyframes> <objectanimationusingkeyframes storyboard.targetproperty="(grid.column)" storyboard.targetname="stackpanel2"> <discreteobjectkeyframe keytime="0" value="0"/> </objectanimationusingkeyframes> <!-- content --> <objectanimationusingkeyframes storyboard.targetproperty="(grid.row)" storyboard.targetname="content"> <discreteobjectkeyframe keytime="0" value="2"/> </objectanimationusingkeyframes> <objectanimationusingkeyframes storyboard.targetproperty="(grid.column)" storyboard.targetname="content"> <discreteobjectkeyframe keytime="0" value="0"/> </objectanimationusingkeyframes> <objectanimationusingkeyframes storyboard.targetproperty="(grid.columnspan)" storyboard.targetname="content"> <discreteobjectkeyframe keytime="0" value="3"/> </objectanimationusingkeyframes> <! -- blue section --> <objectanimationusingkeyframes storyboard.targetproperty="(grid.row)" storyboard.targetname="bluesection"> <discreteobjectkeyframe keytime="0" value="3"/> </objectanimationusingkeyframes> <objectanimationusingkeyframes storyboard.targetproperty="(grid.column)" storyboard.targetname="bluesection"> <discreteobjectkeyframe keytime="0" value="0"/> </objectanimationusingkeyframes> <objectanimationusingkeyframes storyboard.targetproperty="(grid.columnspan)" storyboard.targetname="bluesection"> <discreteobjectkeyframe keytime="0" value="3"/> </objectanimationusingkeyframes> <!-- footer --> <objectanimationusingkeyframes storyboard.targetproperty="(grid.row)" storyboard.targetname="footer"> <discreteobjectkeyframe keytime="0" value="4"/> </objectanimationusingkeyframes> </visualstate> </visualstategroup> <visualstatemanager.visualstategroups> </grid> you're done. need left page listen windowsizechanged , respond it! needs reference grid. such, suggest adding x:name="contentgrid" or similar base grid definition. such as:
<grid x:name="contentgrid"> my example windowsizechanged assume have done this.
private void windowsizechanged(object sender, windowsizechangedeventargs windowsizechangedeventargs) { if (windowsizechangedeventargs.size.width < 800) { visualstatemanager.gotostate(contentgrid, "portrait", true); } else { visualstatemanager.gotostate(contentgrid, "landscape", true); } } then, in page's onnavigatedto , onnavigatedfrom...
protected override void onnavigatedto(navigationeventargs e) { window.current.sizechanged += windowsizechanged; } protected override void onnavigatedfrom(navigationeventargs e) { window.current.sizechanged -= windowsizechanged; } make sure remove sizechanged event handler on navigating page, otherwise app retain copy of page in memory indefinitely. how create fun memory leak.
and that's it! on size changed, main page notify grid needs reconfigure , in way described. won't able directly paste in, should able use lot of it. make sure change targetnames named controls.
hope helps , happy coding!
Comments
Post a Comment