天天看點

win10 uwp 簡單MasterDetail

中文

​​English​​

本文主要講實作一個簡單的界面,可以在視窗比較大顯示清單和内容,視窗比較小時候顯示清單或内容。也就是在視窗比較小的時候,點選清單會顯示内容,點選傳回會顯示清單。

先放圖,很簡單。

開始的視窗是大,顯示清單,因為開始沒有點選清單就顯示圖檔,點選清單顯示内容,就是下面的圖。

win10 uwp 簡單MasterDetail
win10 uwp 簡單MasterDetail

如果螢幕小,那麼顯示清單或内容

當然可以看下垃圾wr的

然後發下我的,可以看到我的最垃圾

win10 uwp 簡單MasterDetail
win10 uwp 簡單MasterDetail

https://msdn.microsoft.com/windows/uwp/controls-and-patterns/master-details

國内曉迪文章很好,但是對我渣渣很難。

本文是很簡單的,一般和我一樣渣都能大概知道。

代碼其實我在很大的壓力會議寫的,不到一個鐘,寫完修改,和大家說,我寫的很簡單,可以修改我代碼,可以自己寫

我們首先一個Grid,分為兩欄,其中一欄為List,一欄為Content

在大屏,也就是我們可以把Grid兩欄顯示,基本就是Frame導航就好了。

如果螢幕小,我們合并為一個Grid,使用順序,對,List和Content的Zindex設定他們的位置,Zindex比較大的會顯示,也就是判斷是否存在Content,存在就顯示他,不存在,顯示List。

應該可以看懂。

現在來說Frame導航。

UWP 導航

Content是一個Frame和一個Image的Grid

<Grid Grid.Column="{x:Bind View.GridInt,Mode=OneWay}" x:Name="Img" 

                  Canvas.ZIndex="{x:Bind View.ZFrame,Mode=OneWay}">

                <Image  Source="../Assets/images.jpg"

                       ></Image>

                <Frame x:Name="frame"

                       ></Frame>

            </Grid>      

先不要Grid的屬性,我會在後面說。

我們沒Frame的Content,也就是我們沒點選List,會顯示圖檔,Frame有頁面就不會顯示,因為ZIndex Frame比Image大,很簡單

頁面傳參數很簡單,首先是Frame

FrameNavigate(typeof(頁), 參數);      

我們在參數寫我們要傳頁面

在頁面

protected override void OnNavigatedTo(NavigationEventArgs e)

        {

            var 參數= e.Parameter as 傳輸的參數;

            base.OnNavigatedTo(e);

        }      

如果要儲存我們的頁面,不要導航都建立,在構造​

​NavigationCacheMode = NavigationCacheMode.Enabled;​

List點選

我們建立資料Model,我們使用MVVM

public class AddressBook

    {

        public string Id { set; get; }

        public string Name { set; get; }

        public string Str { set; get; }

    }      

随便的,可以根據你需要修改

我們在ViewModel,我在View建立兩個​

​DetailPage.xaml​

​​ ​

​MasterDetailPage.xaml​

​,是以在ViewModel DetailMasterModel.cs

我們在裡面

public ObservableCollection<AddressBook> EccryptAddress { set; get; }      

記住要修改列的數量需要使用的

然後我們需要在View寫,讓我們的資料顯示

<ListView ItemClick="{x:Bind View.MasterClick}"

                      IsItemClickEnabled="True"

                      ItemsSource="{x:Bind View.EccryptAddress}"

                      >

                    <ListView.ItemTemplate>

                        <DataTemplate x:DataType="view:AddressBook">

                            <Grid>

                                <TextBlock Text="{x:Bind Name}"></TextBlock>

                            </Grid>

                        </DataTemplate>

                    </ListView.ItemTemplate>

                </ListView>      

當然需要我們在view.xaml.cs

public MasterDetailPage()

        {

            View = new DetailMasterModel();

            this.InitializeComponent();

        }

        private DetailMasterModel View { set; get; }      

我們給ListView我們ViewModel的資料,這樣就可以顯示,我們使用ItemClick可以得到ListView被點選,當然要​

​IsItemClickEnabled="True"​

public void MasterClick(object o, ItemClickEventArgs e)

        {

            AddressBook temp = e.ClickedItem as AddressBook;

            if (temp == null)

            {

                return;

            }

            HasFrame = true;

            Detail.Navigate(typeof(DetailPage), temp.Str);

            Narrow();

        }      

我們拿到點選傳給Frame,在ViewModel,把Frame叫Detail

因為點選是以我們的Frame有内容 HasFrame=true;

後退按鈕

在App寫

Windows.UI.Core.SystemNavigationManager.GetForCurrentView().AppViewBackButtonVisibility = Windows.UI.Core.AppViewBackButtonVisibility.Visible;      

我們在ViewModel

SystemNavigationManager.GetForCurrentView().BackRequested += BackRequested;      

如果不知道我說的是什麼,可以去下我源代碼https://github.com/lindexi/UWP

然後在按後退按鈕,就把我們的hasFrame=false;

大概我們就把一個頁面做好,Detail就顯示我們點選傳的str

我們需要手機按後退也是 ​

​Windows.Phone.UI.Input.HardwareButtons.BackPressed​

頁面更改大小

我們獲得頁面大小修改,可以簡單

<VisualStateManager.VisualStateGroups >

            <VisualStateGroup CurrentStateChanged="{x:Bind View.NarrowVisual}">

                <VisualState>

                    <VisualState.StateTriggers>

                        <AdaptiveTrigger MinWindowWidth="720"/>

                    </VisualState.StateTriggers>

                    <VisualState.Setters >

                        <!--<Setter Target="Img.Visibility" Value="Collapsed"></Setter>-->

                    </VisualState.Setters>

                </VisualState>

                <VisualState>

                    <VisualState.StateTriggers>

                        <AdaptiveTrigger MinWindowHeight="200">

                        </AdaptiveTrigger>

                    </VisualState.StateTriggers>

                    <VisualState.Setters >

                    </VisualState.Setters>

                </VisualState>

            </VisualStateGroup>

        </VisualStateManager.VisualStateGroups>      
public void NarrowVisual(object sender, VisualStateChangedEventArgs e)

        {

            Narrow();

        }      

CurrentStateChanged就是當觸發我們的界面變化發生,用這個比較好,因為我們界面大小修改不一定會小于我們設定的,一旦小于再觸發,因為View的函數需要​

​object sender, VisualStateChangedEventArgs e​

那麼從函數獲得我們視窗變化可以使用下面兩個:

Window.Current.Bounds.Width放在函數,就可以得到我們的視窗大小。

當然我們可以給我們VisualState名,從e.NewState拿到Name就很簡單,我們使用Narrow,判斷顯示屏是小還是可以顯示兩個

我推薦是使用第一個,因為第二個我們必須修改前台就修改ViewModel

修改顯示

我們先判斷我們現在螢幕,顯示兩個還是顯示List一個,如果是顯示兩個,那麼我們不需要什麼,當然我們需要給預設。

預設Grid左邊Auto,右邊*,分兩個,然後左邊是List,如果沒有Frame,那麼顯示圖檔

如果屏小,那麼就顯示List,這時我們修改Grid為左邊*,右邊auto,然後把我們Grid,有Frame,修改為左邊,這樣我們右邊就沒有,左邊有List和Grid

如果我們HasFrame,還記得hasFrame在哪?就是我們Frame存在内容就是true,那麼我們把Frame的ZIndex>List的ZIndex,我們就顯示Frame,如果我們按傳回,那麼把List的ZIndex大于Frame

可以看到我們需要設定一個ZIndex就好

我們就在界面變化,和點選後悔,點選清單,使用判斷,我們判斷寫成一個函數,函數判斷現在視窗,判斷HasFrame,很簡單。

如果看不懂我上面說的,可以看我代碼https://github.com/lindexi/UWP/tree/master/uwp/src/DetailMaster

我們開始的大螢幕是使用Grid有分開,左邊清單,右邊Content,其中Content是Frame,用到頁面導航。

如果螢幕小,那麼使用List和Content放在同一個Grid,依靠Zindex顯示,如果是需要顯示清單就清單的ZIndex大,需要顯示内容,就把内容的ZIndex大。

我們需要判斷我們是否點選了List和使用者是否點了傳回鍵,一旦按傳回鍵,我們顯示清單,當然在我們螢幕大,可以不做什麼,如果螢幕小,就需要設定ZIndex。

那麼我們在界面變化的是否,是否知道我們顯示内容還是顯示清單,這時就是我們得HasFrame,依靠這個選擇ZIndex

修改我代碼

現在需要說下,如何修改我的代碼,作為你需要。

一般可以自己寫一個,不過通過修改我的代碼會讓你更加了解

首先我們需要Model,這是你自己定義的,随便寫

然後打開ViewModel,我們裡面關鍵的有ObservableCollection的,這是清單。

MasterClick裡面把跳轉換為你需要的。

BackRequested是傳回,按傳回鍵,我們現在簡單使用界面的,不使用硬體,如果需要硬體其實簡單。

界面開始的Image可以換為你需要的,然後其他的可以選擇不修改。

很簡單使用。

源碼

接着我們來說下我源代碼怎麼做。

我首先建立Model,放下随意的,然後在ViewModel使用ObservableCollection,當然給他的也是随意的

在界面我們需要Grid,這時我綁定了GridLength,設定這個簡單。

如果需要auto,簡單 ​

​GridLength.Auto​

​​,如果需要​

​1*​

​​,可以​

​new GridLength(1, GridUnitType.Star);​

​​就是這樣,開始是左邊Auto,右邊​

​1*​

​,MasterGrid就是清單啦,這個不想說

我綁定是用x:Bind,要OneWay

我寫List需要使用Grid,因為背景透明,其實我在List也可以用背景,但是我想我會在List做彈出,最後想着用Grid

<Grid

                Background="White"

                Canvas.ZIndex="{x:Bind View.ZListView,Mode=OneWay}">      

在List

<Grid Grid.Column="{x:Bind View.GridInt,Mode=OneWay}"

                  Canvas.ZIndex="{x:Bind View.ZFrame,Mode=OneWay}">      

我們需要做一點修改,在我們的内容沒有,我們是不需要傳回鍵的,那麼這時的傳回鍵可以作為按兩次退出,這個可以看​

如果我們按傳回,但是我們撸了一半,假如我們是頁面跳轉,不使用我源碼,那麼加上NavigationCacheMode ,儲存頁面,這樣不會讓頁面現在的選擇重新

下面說下English,其實是Google翻譯,因為我這個遇到一個用英文問我的人,不知道是不是,反正就直接翻譯

English

I make a Easy MasterDetail to use.It’s very easy,and I has not yet been see the other easier that it.

In big screen and the widescreen,we have a Grid with two columns.And the left is list and the right is content.

The content is an Image and a Frame.If not content,show Image,else show content.

In narrowscreen,we make the list and content in a col.If has content ,the content’s Zindex is greater than the list.And if click the backButton ,the List’s zindex is greater than content.

We make the list’s background white,so if the list zindex is grerater than content and we can’t see content.

We have bool value is hasFrame ,if we has content ,it is true,else false.In the windows be narrow ,if the hasFrame==true ,we make Content’s zindex greater than list.

We can change the model for your class and write ObservableCollection.In ​

​MasterClick​

​ ,we can make Navigate.

If something perplexes you,mailto [email protected].