2012年7月13日 星期五

GridView + VariableSizedWrapGrid

使用 XMAL 撰寫 Windows 8 Metro Style App 的人應該可以試試看…
若想要寫出像 Windows Store 那樣可變尺寸項目組成的 GridView 是不容易的…

一般 VariableSizedWrapGrid 只要將子元件的 RowSpan、ColumnSpan 定義清楚即可…
但若使用 GridView 時…不論是否有做 Group 皆會失效…
由於我個人只懂得用 XMAL 刻 UI 所以這問題還蠻嚴重的…
公司同事使用 JavaScript + CSS 倒是由於表達方式不同…相當容易做出這種排版效果…
所幸在下關鍵字搜尋後…很快就找到一位微軟人員給的範例…測試後可以運作…相當好…

http://social.msdn.microsoft.com/Forums/en-US/winappswithcsharp/thread/966aa897-1413-46f0-bef7-663de36f9423

簡單的整理一下重點…大致上在 ItemTemplate 時指定 Span 屬性是沒有用的…
必須覆寫 PrepareContainerForItemOverride 這個 Method
在參數列中的 object item 即是 GridView 所 Binding 的物件項目…
只要將其轉型為你自行定義的類別後…再由此 item 取出資訊重新設定 Span 的值即可…
當然你所自行定義的類別中得要有資訊記錄自己的大小…範例如下…

protected override void PrepareContainerForitemOverride(Windows.UI.Xaml.DependencyObject element, object item)
{
    base.PrepareContainerFoitmOverride(element, item);

    ItemBase itm = (ItemBase)item;

    if (itm.ItemTemplateType == ItemBase.TEMPLATE_TYPE.LARGE)
    {
        VariableSizedWrapGrid.SetRowSpan((UIElement)element, 2);
        VariableSizedWrapGrid.SetColumnSpan((UIElement)element, 2);
    }
    else if (itm.ItemTemplateType == ItemBase.TEMPLATE_TYPE.MEDIUM)
    {
        VariableSizedWrapGrid.SetRowSpan((UIElement)element, 2);
        VariableSizedWrapGrid.SetColumnSpan((UIElement)element, 1);
    }
    else
    {
        VariableSizedWrapGrid.SetRowSpan((UIElement)element, 1);
        VariableSizedWrapGrid.SetColumnSpan((UIElement)element, 1);
    }
}

根本的原因我不太清楚…但看這裡執行的順序看起來…必須在項目 Binding 及呈現後…
再對其設定 RowSpan、ColumnSpan 才會生效…讓我想到在撰寫 Windows 程式時…
若在視窗生成時對視窗設 wndTopMost 屬性…在 Windows 7 上面常常會失效…
必須在 WM_ACTIVATE 時設定才能確保行為正常的狀況…

沒有留言:

張貼留言