所谓 UWP 样式的达拉斯菜单,笔者曾在“张快意的 UWP
开采笔记:开普敦菜单进阶”里说过,也正是接纳Segoe MDL二 Assets 字体作为左边 Icon,并且左侧使用填充颜色的矩形用来代表
ListView 的选中。如下图

  所谓 UWP 样式的拉各斯菜单,笔者曾在“张满面春风的 UWP
开辟笔记:布达佩斯菜单进阶”里说过,也正是利用
Segoe MDL2 Assets 字体作为左边 Icon,并且左边使用填充颜色的矩形用来代表
ListView 的选中。如下图

在开辟XX信息的进度中,UI部分使用了Master/Detail(大纲/细节)布局样式。Win10系统中的邮件App就是这种体制,左边多少个列表,左边是详细的情况页面。关于那种
样式的表达可参照MSDN文书档案:

图片 1

图片 1

体制如下:

  但怎么着通过 Xamarin.Forms ,将那一体制的波士顿菜单带入到 Android 与 iOS
中吗?

  但怎么样通过 Xamarin.Forms ,将那同样式的开普敦菜单带入到 Android 与 iOS
中呢?

图片 3

 

 

在微软官方的萨姆ple里,有那种样式的代码示例,下载地址:

  一、大纲-细节方式简单介绍

  一、大纲-细节方式简要介绍

其一事例能够拿来直接用。处理那种布局,首就算索要处理在PC/Mobile差别显示屏宽度下的切实可行展现内容,能够应用VisualState来落到实处不一样境况的切换。

  讲代码前先是来讲说那种导航航空模型型式,官方称“大纲-细节形式”(MasterDetail)。左边的休斯敦菜单称为“大纲”(Master),右边的页面称为“细节”(Detail)。Xamarin.Froms
为品种提供了许多样导航航空模型型式,“大纲-细节”为内部1种。

  讲代码前先是来讲说那种导航航空模型型式,官方称“大纲-细节情势”(MasterDetail)。右侧的布加勒斯特菜单称为“大纲”(Master),左侧的页面称为“细节”(Detail)。Xamarin.Froms
为品种提供了多少种导航航空模型型式,“大纲-细节”为个中一种。

为了将WP八.一本子的类型急忙升高到UWP版本,小编未有使用官方示例的办法,而是在MainPage里放了多少个Frame,在右侧的Frame里放三个列表Page,右边Frame里放一个端详Page,那样此前的页面包车型大巴UI和ViewModel都足以未有丝毫改造的拿过来,只必要单独处理VisualState的切换就可以了。

 

 

上面以二个简便的事例来说一下是如何达成的。近日有关Win十UWP的剧情写了众多,都以在开辟的进程中,把能独立拿出来的部分再重复做二次demo,所以若是我们风乐趣的话能够照着出手敲二次,本身达成出来才会通晓的更加深远。

  贰、项目简要介绍

  2、项目简单介绍

壹、新建项目及Model

率先新建三个MVVM-Sidekick项目,命名称叫MasterDetail德姆o。

增加Models目录,新建3个NewsItem:

public class NewsItem
{
public int Id { get; set; }
public DateTime DateCreated { get; set; }
public string Title { get; set; }
public string Text { get; set; }
}

 

 

新建1个ItemsDataSource类,用于模拟数据,能够回到一些数量。具体代码看德姆o里的。

private static List<NewsItem> _items = new List<NewsItem>()

{

new NewsItem()
{}……
}

public static IList<NewsItem> GetAllItems()
{
return _items;
}

public static NewsItem GetItemById(int id)
{
return _items[id];
}

 

 

  效果图:

  效果图:

2、页面布局

在MainPage中放置二个Grid控件,分为两列,左边和右侧分别放多个Frame控件:

<Grid x:Name="gridMain" >
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="0" />
    </Grid.ColumnDefinitions>
    <Frame x:Name="masterFrame" Grid.Column="0" mvvm:StageManager.Beacon="masterFrame" x:FieldModifier="public"/>
    <Frame x:Name="detailFrame" HorizontalAlignment="Stretch" Grid.Column="1" mvvm:StageManager.Beacon="detailFrame" x:FieldModifier="public">
    </Frame>
</Grid>            

 

 

下一场加多多少个页面,MasterPage和DetailPage。

MasterPage中放置三个ListView控件,调用刚才的ItemsDataSource类,把数据绑定到ListView上,那些就毫无详述了啊。还要给ListView设置项模板。那部分代码就不贴了。

如今让MainPage页面载入时,左边的Frame自动展现MasterPage。

打开MainPage_Model.cs文件,撤除对OnBindedViewLoad方法的笺注,修改为以下代码:

protected override async Task OnBindedViewLoad(MVVMSidekick.Views.IView view)
{
    await base.OnBindedViewLoad(view);
    await StageManager["masterFrame"].Show(new MasterPage_Model());

}

 

 

好了,今后当MainPage页面加载成功后,名叫masterFrame的Frame会展现MasterPage的剧情,像上面那样:

图片 4

然后要完毕点击项的时候,要在左边的Frame里显示DetailPage。

开垦MasterPage.xaml,在头顶引进以下多少个命名空间:

xmlns:Interactivity="using:Microsoft.Xaml.Interactivity"
xmlns:Core="using:Microsoft.Xaml.Interactions.Core"
xmlns:Behaviors="using:MVVMSidekick.Behaviors"

 

下一场修改项模板,使用SendTo伊芙ntRouterAction,这些东东在原先的Blog里说过,在项模板的Grid里增加以下代码:

<Interactivity:Interaction.Behaviors>
    <Core:EventTriggerBehavior EventName="Tapped">
        <Behaviors:SendToEventRouterAction EventRoutingName="NewsItemTapped" EventData="{Binding}" IsEventFiringToAllBaseClassesChannels="True" />
    </Core:EventTriggerBehavior>
</Interactivity:Interaction.Behaviors>    

 

 

在MainPage加载的时候,注册NewsItemTapped事件,来拍卖点击事件。打开MainPage_Model.cs文件,在终极加多1个RegisterCommand方法:

private void RegisterCommand()
{
     MVVMSidekick.EventRouting.EventRouter.Instance.GetEventChannel<Object>()
.Where(x => x.EventName == "NewsItemTapped")
.Subscribe(
e =>
    {
        NewsItem item = e.EventData as NewsItem;
        await StageManager["detailFrame"].Show(new DetailPage_Model(item));
    }
    ).DisposeWith(this);
}    

 

别忘了在Loaded事件里调用这一个办法:

protected override async Task OnBindedViewLoad(MVVMSidekick.Views.IView view)
{
    this.RegisterCommand();
    await base.OnBindedViewLoad(view);
    await StageManager["masterFrame"].Show(new MasterPage_Model());
}

 

因为DetailPage_Model还并未有可采用参数的构造函数,所以要求在DetailPage_Model里加八个构造函数,1个是无参的,一个是可接受参数的,同时还亟需加3个可绑定的习性,用来展示内容:

public DetailPage_Model()
{ }


public DetailPage_Model(NewsItem item)
{
    CurrentNewsItem = item;
}



public NewsItem CurrentNewsItem
{
get { return _CurrentNewsItemLocator(this).Value; }
set { _CurrentNewsItemLocator(this).SetValueAndTryNotify(value); }
}

#region Property NewsItem CurrentNewsItem Setup

protected Property<NewsItem> _CurrentNewsItem = new Property<NewsItem> { LocatorFunc = _CurrentNewsItemLocator };

static Func<BindableBase, ValueContainer<NewsItem>> _CurrentNewsItemLocator = RegisterContainerLocator<NewsItem>("CurrentNewsItem", model => model.Initialize("CurrentNewsItem", ref model._CurrentNewsItem, ref _CurrentNewsItemLocator, _CurrentNewsItemDefaultValueFactory));

static Func<NewsItem> _CurrentNewsItemDefaultValueFactory = () => { return default(NewsItem); };

#endregion

 

那样在DetailPage里就足以接到到点击的是哪位NewsItem了,再绑定到分界面上,作者就不管放了个TextBlock:

<StackPanel x:Name="RootPanel" Grid.Row="1">
<TextBlock
Margin="8,0"
Style="{ThemeResource TitleTextBlockStyle}"
HorizontalAlignment="Left"
Text="{Binding CurrentNewsItem.Title}" />
<TextBlock
Margin="12,8"
HorizontalAlignment="Left"
MaxWidth="560"
Style="{ThemeResource BodyTextBlockStyle}"
Text="{Binding CurrentNewsItem.Text}"
EntranceNavigationTransitionInfo.IsTargetElement="True" />
</StackPanel>

 

运行一下看望,怎么点了没影响呢,原来在MainPage的Grid里,第1列就把宽度占满了,第一列不可能展现了,来给四个列设置个增长幅度吧,第一列设置为二*,第三列设置为三*:

近年来得以彰显了:

图片 5

图片 6

图片 6

三、自定义StateTrigger

只是,这只是率先步,接下去须求处理在分裂显示屏宽度下的适配难题,大家得以张开UWP版的邮件,拖动窗口缩放大小,观望页面内容更动,可以得出以下特点:

在PC上:

一、当宽度超过一定幅度时,Master和Detail是能够同时彰显的,在刚展开程序未有点击邮件的时候,左边的Detail实际上展现了三个空页面(有背景图片);

当稳步减弱宽度时,又分为三种状态:

二、借使Detail页为空页面时,减弱到自然幅度后,窗口只浮现Master页面;

3、如若Detail页不为空,即呈现邮件正文的时候,减弱到早晚幅度后,窗口只展现Detail页面;

在Mobile上:

次第张开时,显示Master页面,相当于2;

点击邮件后,显示Detail页面,相当于三;

如此那般我们得以汲取,不管是PC照旧Mobile,须求处理三种情况的切换,作者取名叫:

NarrowAndBlankDetail

NarrowAndNoBlankDetail

Wide

透过拍卖这两种状态的切换,就足以兑现类似邮件UWP版的功力了。某个同学只怕会问,为何不直接利用自带的AdaptiveTrigger呢,首借使其一AdaptiveTrigger只好根据宽度来安装,而当前的供给还需求依照Detail页面是或不是为空来处理,所以需求自定义贰个Trigger了。

邮件UWP暗中同意载入的时候有三个空页面,所以还索要增加1个BlankPage,那么些页面也正是一个空页面,里面能够不管放点什么事物,比如背景图片啊,logo啊,只怕广告怎样的,Trigger会依照Detail页面是还是不是出示那几个BlankPage来拓展处理。

先让MainPage载入时,暗中同意左边加载MasterPage,左边加载BlankPage:

protected override async Task OnBindedViewLoad(MVVMSidekick.Views.IView view)
{
    this.RegisterCommand();
    await base.OnBindedViewLoad(view);
    StageManager["detailFrame"].Show(new BlankPage_Model());
    await StageManager["masterFrame"].Show(new MasterPage_Model());
}

 

好,运营效果是这么:

图片 8

后天来拍卖情状切换。关于StateTrigger,海外已经有人写了3个体系,完结了各类Trigger,见:

运用介绍见:http://www.sharpgis.net/post/2015/03/24/Using-Custom-Visual-State-Triggers

那些项目完毕了n个实用的Trigger,但好心痛未有能满意自家的渴求的,依然要好动手吧。作者参考了他的代码,承继了他的接口ITriggerValue,承袭此接口的话能够用在CompositeStateTrigger里,为了方便以往选拔根据这一个接口来吧。

说一下第二的代码达成思路。

先是要定义2个枚举:

public enum MasterDetailState
{
/// <summary>
/// narrow and a blank detail page
/// </summary>
NarrowAndBlankDetail,

/// <summary>
/// narrow and detail page is not blank
/// </summary>
NarrowAndNoBlankDetail,

/// <summary>
/// wide
/// </summary>
Wide
}

 

页面宽度的生成,通过订阅ApplicationView.GetForCurrentView().VisibleBoundsChanged事件来拍卖,假使幅度超越720时怎么,小于720时怎么。当然这一个720也足以传递属性进来,笔者懒得弄就写死在内部了。

还要,还索要八个DetailContent属性,这些本性需求绑定到第三个Frame的Content上,这样Trigger能够了解当前是或不是BlankPage,通过以下代码来决断:

MVVMPage detailPage = (MVVMSidekick.Views.MVVMPage)DetailContent;
if (detailPage != null)
{
if (detailPage.BaseUri.ToString() == "ms-appx:///BlankPage.xaml")
{
System.Diagnostics.Debug.WriteLine("触发NarrowAndBlankDetail模式");
//CommonContext.Instance.CurrentBackRequestedHandlerType = BackRequestedHandlerType.MasterPage;
return MasterDetailState.NarrowAndBlankDetail;
}
else
{
System.Diagnostics.Debug.WriteLine("触发NarrowAndNoBlankDetail模式");
//CommonContext.Instance.CurrentBackRequestedHandlerType = BackRequestedHandlerType.DetailPage;
return MasterDetailState.NarrowAndNoBlankDetail;
}
}

 

全总代码如下:

图片 9图片 10

public class MasterDetailStateTrigger : StateTriggerBase, ITriggerValue

{





public MasterDetailStateTrigger()

{

if (!Windows.ApplicationModel.DesignMode.DesignModeEnabled)

{



var weakEvent =

new WeakEventListener<MasterDetailStateTrigger, ApplicationView, object>(this)

{

OnEventAction = (instance, source, eventArgs) => MasterDetailStatetateTrigger_MasterDetailStateChanged(source, eventArgs),

OnDetachAction = (instance, weakEventListener) => ApplicationView.GetForCurrentView().VisibleBoundsChanged -= weakEventListener.OnEvent

};

ApplicationView.GetForCurrentView().VisibleBoundsChanged += weakEvent.OnEvent;



}

}



private void MasterDetailStatetateTrigger_MasterDetailStateChanged(ApplicationView sender, object args)

{

UpdateTrigger();

}



private void UpdateTrigger()

{

IsActive = GetMasterDetailState() == MasterDetailState;



}













public MasterDetailState MasterDetailState

{

get { return (MasterDetailState)GetValue(MasterDetailStateProperty); }

set { SetValue(MasterDetailStateProperty, value); }

}



// Using a DependencyProperty as the backing store for MasterDetailState. This enables animation, styling, binding, etc...

public static readonly DependencyProperty MasterDetailStateProperty =

DependencyProperty.Register("MasterDetailState", typeof(MasterDetailState), typeof(MasterDetailStateTrigger), new PropertyMetadata(MasterDetailState.Wide, OnMasterDetailStatePropertyChanged));



private static void OnMasterDetailStatePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)

{



var obj = (MasterDetailStateTrigger)d;

if (!Windows.ApplicationModel.DesignMode.DesignModeEnabled)

{

obj.UpdateTrigger();

}

}











public object DetailContent

{

get { return (object)GetValue(DetailContentProperty); }

set { SetValue(DetailContentProperty, value); }

}



// Using a DependencyProperty as the backing store for DetailContent. This enables animation, styling, binding, etc...

public static readonly DependencyProperty DetailContentProperty =

DependencyProperty.Register("DetailContent", typeof(object), typeof(MasterDetailStateTrigger), new PropertyMetadata(null, new PropertyChangedCallback(OnValuePropertyChanged)));



private static void OnValuePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)

{

var obj = (MasterDetailStateTrigger)d;

obj.UpdateTrigger();

}









internal MasterDetailState GetMasterDetailState()

{

System.Diagnostics.Debug.WriteLine("DetailContent为空:" + (DetailContent == null).ToString());

//第一种 窄屏模式 DetailFrame为空

if (Window.Current.Bounds.Width < 720)

{

System.Diagnostics.Debug.WriteLine("VisibleBounds.Width:" + ApplicationView.GetForCurrentView().VisibleBounds.Width.ToString());

System.Diagnostics.Debug.WriteLine("Window.Current.Bounds:" + Window.Current.Bounds.Width.ToString());

MVVMPage detailPage = (MVVMSidekick.Views.MVVMPage)DetailContent;

if (detailPage != null)

{

if (detailPage.BaseUri.ToString() == "ms-appx:///BlankPage.xaml")

{

System.Diagnostics.Debug.WriteLine("触发NarrowAndBlankDetail模式");

return MasterDetailState.NarrowAndBlankDetail;

}

else

{

System.Diagnostics.Debug.WriteLine("触发NarrowAndNoBlankDetail模式");

return MasterDetailState.NarrowAndNoBlankDetail;

}

}

else

{

return MasterDetailState.NarrowAndBlankDetail;

}

}

else

{

System.Diagnostics.Debug.WriteLine("触发Wide模式");

return MasterDetailState.Wide;

}

}







#region ITriggerValue



private bool m_IsActive;



/// <summary>

/// Gets a value indicating whether this trigger is active.

/// </summary>

/// <value><c>true</c> if this trigger is active; otherwise, <c>false</c>.</value>

public bool IsActive

{

get { return m_IsActive; }

private set

{

if (m_IsActive != value)

{

m_IsActive = value;

base.SetActive(value);

if (IsActiveChanged != null)

IsActiveChanged(this, EventArgs.Empty);

}

}

}



/// <summary>

/// Occurs when the <see cref="IsActive" /> property has changed.

/// </summary>

public event EventHandler IsActiveChanged;



#endregion ITriggerValue







}



public enum MasterDetailState

{

/// <summary>

/// narrow and a blank detail page

/// </summary>

NarrowAndBlankDetail,

/// <summary>

/// narrow and detail page is not blank

/// </summary>

NarrowAndNoBlankDetail,

/// <summary>

/// wide

/// </summary>

Wide

}

View Code

 

自作者在代码里输出了有个别新闻,调节和测试的时候能够洞察各类境况是在怎么样时候切换的。

接下来在MainPage.xaml里
应用那一个StateTrigger,首先,要在MainPage的ViewModel里增加贰个object,用于绑定DetailFrame的剧情:

/// <summary>
/// detailFrame的内容
/// </summary>
public object DetailContent
{
get { return _DetailContentLocator(this).Value; }
set { _DetailContentLocator(this).SetValueAndTryNotify(value); }
}

#region Property object DetailContent Setup

protected Property<object> _DetailContent = new Property<object> { LocatorFunc = _DetailContentLocator };

static Func<BindableBase, ValueContainer<object>> _DetailContentLocator = RegisterContainerLocator<object>("DetailContent", model => model.Initialize("DetailContent", ref model._DetailContent, ref _DetailContentLocator, _DetailContentDefaultValueFactory));

static Func<object> _DetailContentDefaultValueFactory = () => default(object);

#endregion

 

MainPage.xaml里的第壹个Frame的Content绑定到那么些DetailContent上:

<Frame x:Name="detailFrame" Content="{Binding DetailContent,Mode=TwoWay}" HorizontalAlignment="Stretch" Grid.Column="1" mvvm:StageManager.Beacon="detailFrame" x:FieldModifier="public">

 

在意Mode要安装为TwoWay,那样才方可让Trigger知道DetaiFrame的剧情。在MainPage.xaml的根Grid里增添以下Trigger:

<VisualStateManager.VisualStateGroups>
    <VisualStateGroup>
        <VisualState x:Name="NarrowAndBlankDetail">
            <VisualState.StateTriggers>
                <triggers:MasterDetailStateTrigger MasterDetailState="NarrowAndBlankDetail" DetailContent="{Binding DetailContent}" />
            </VisualState.StateTriggers>
        <VisualState.Setters>
            <Setter Target="gridMain.ColumnDefinitions[0].Width" Value="*" />
            <Setter Target="gridMain.ColumnDefinitions[1].Width" Value="0" />
        </VisualState.Setters>
    </VisualState>
    <VisualState x:Name="NarrowAndNoBlankDetail">
        <VisualState.StateTriggers>
            <triggers:MasterDetailStateTrigger MasterDetailState="NarrowAndNoBlankDetail" DetailContent="{Binding DetailContent}" />
           </VisualState.StateTriggers>
        <VisualState.Setters>
            <Setter Target="gridMain.ColumnDefinitions[0].Width" Value="0" />
            <Setter Target="gridMain.ColumnDefinitions[1].Width" Value="*" />
        </VisualState.Setters>
        </VisualState>
        <VisualState x:Name="Wide">
            <VisualState.StateTriggers>
                <triggers:MasterDetailStateTrigger MasterDetailState="Wide" DetailContent="{Binding DetailContent}" />
            </VisualState.StateTriggers>
        <VisualState.Setters>
            <Setter Target="gridMain.ColumnDefinitions[0].Width" Value="2*" />
            <Setter Target="gridMain.ColumnDefinitions[1].Width" Value="3*" />
        </VisualState.Setters>
        </VisualState>
    </VisualStateGroup>
</VisualStateManager.VisualStateGroups>    

 

还要把暗中认可的gridMain的两列的大幅度暗中同意值分别改为*和0:

<Grid x:Name="gridMain" >
    <Grid.RenderTransform>
        <CompositeTransform />
    </Grid.RenderTransform>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="0" />
    </Grid.ColumnDefinitions>
    <Frame x:Name="masterFrame" Grid.Column="0" mvvm:StageManager.Beacon="masterFrame" x:FieldModifier="public"/>
    <Frame x:Name="detailFrame" Content="{Binding DetailContent,Mode=TwoWay}" HorizontalAlignment="Stretch" Grid.Column="1" mvvm:StageManager.Beacon="detailFrame" x:FieldModifier="public">
</Frame>

</Grid>

 

Trigger的意思很清楚了,Setter会依照不一致的情状去设置gridMain两列的大幅来支配MasterPage和DetailPage的来得和隐藏:

当刚初叶进入程序,右侧显示列表,左侧彰显BlankPage,这时候即使幅度超越720,八个页面寻常展示,若是页面宽度小于720,则只展现列表页;

若果页面宽度当先720的时候,点击列表,右边符合规律展现详细的情况;

如果页面宽度小于720,点击列表,列表会隐藏,只体现实际情况;

骨干实现了稿子初叶提议的目标。

  不多说废话,看代码实在些。

  不多说废话,看代码实在些。

四、处理重回键

当在四弟大上运转的时候,就会发现当点击列表展现DetailPage后,再按再次来到键直接退出程序了。因为还一贯不处理重回键事件。PC上也1如既往,程序左上角应该有个再次来到按键。上边来拍卖回来事件。

基本思路是,点击再次来到后,应该先判别DetailPage是还是不是可GoBack,如若得以就GoBack,直到回到最伊始的BlankPage截止,那样StateTrigger会自动触发NarrowAndBlankDetail状态,展现MasterPage。

重回是拍卖SystemNavigationManager.GetForCurrentView().BackRequested这一个事件,张开MainPage.xaml.cs文件,在OnNavigatedTo里订阅这么些事件:

protected override void OnNavigatedTo(NavigationEventArgs e)
{
    SystemNavigationManager.GetForCurrentView().BackRequested += CurrentView_BackRequested;
        //SystemNavigationManager.GetForCurrentView().AppViewBackButtonVisibility = AppViewBackButtonVisibility.Visible;
    base.OnNavigatedTo(e);
}



protected override void OnNavigatedFrom(NavigationEventArgs e)
{
    SystemNavigationManager.GetForCurrentView().BackRequested -= CurrentView_BackRequested;
    base.OnNavigatedFrom(e);
}



private void CurrentView_BackRequested(object sender, BackRequestedEventArgs e)
{
    //判断DetailPage能否GoBack,如果可以GoBack则GoBack 显示BlankPage
    //其次判断MasterPage能否GoBack,如果可以GoBack则GoBack
    //如果不能GoBack,则提示是否退出
    if     (StrongTypeViewModel.StageManager["detailFrame"].CanGoBack)
    {
        e.Handled = true;
        StrongTypeViewModel.StageManager["detailFrame"].Frame.GoBack();
    }
    else if (StrongTypeViewModel.StageManager["masterFrame"].CanGoBack)
    {
        e.Handled = true;
        StrongTypeViewModel.StageManager["masterFrame"].Frame.GoBack();
    }
    else
    {
        //TODO 隐藏回退键 提示退出
        SystemNavigationManager.GetForCurrentView().AppViewBackButtonVisibility = AppViewBackButtonVisibility.Collapsed;
    }
}

 

用户点击再次来到键的时候,首先看DetailPage能还是不可能GoBack,再看MasterPage能或无法GoBack,当未有可GoBack的时候就把重临键隐藏。

在PC上的再次来到键私下认可是暗藏的,还索要在导航到详细情况页的时候将其出示出来,修改MainPage_Model.cs文件里的RegisterCommand方法:

private void RegisterCommand()
{
MVVMSidekick.EventRouting.EventRouter.Instance.GetEventChannel<Object>()
.Where(x => x.EventName == "NewsItemTapped")
.Subscribe(
async e =>
{
NewsItem item = e.EventData as NewsItem;
SystemNavigationManager.GetForCurrentView().AppViewBackButtonVisibility = AppViewBackButtonVisibility.Visible;
await StageManager["detailFrame"].Show(new DetailPage_Model(item));
}
).DisposeWith(this);
}

 

方今运作一下,PC上也得以回去了。当第三次展开的时候,是那般 的:

图片 11

假定拖动窗口减少,则只会来得MasterPage:

图片 12

当点击列表项时,会只呈现DetailPage:

图片 13

点击左上角重回键,又只突显MasterPage了。

切切实实切换动画本人不会截图,我们能够下载demo本身尝试。

  本示例是选取 Visual Studio 20一7 创造的 克罗丝-Platform
项目,项目名称叫”HamburgerMenuDemo“,模板为空白项目。(GitHub:)

  本示例是运用 Visual Studio 2017 创建的 克罗丝-Platform
项目,项目名称为”HamburgerMenuDemo“,模板为空白项目。(GitHub:)

5、增多切换动画效果

咱俩还足以做的更加美观一点。UWP默许的Page切换是有动画效果的,但此间因为只利用StateTrigger设置了Grid的列宽,当从DetailPage再次回到MasterPage的时候MasterPage一下子就体现出来了,以为微微生硬。以往给切换加3个卡通。

在NarrowAndBlankDetail的VisualState里,加多一段StoryBoard:

<Storyboard >
    <DoubleAnimation Storyboard.TargetName="gridMain" Storyboard.TargetProperty="Opacity" From="0" To="1" Duration="0:0:0.6">
        <DoubleAnimation.EasingFunction>
            <CircleEase EasingMode="EaseOut" />
        </DoubleAnimation.EasingFunction>
    </DoubleAnimation>
    <DoubleAnimation Storyboard.TargetName="gridMain" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateX)" From="-100" To="0" Duration="0:0:0.3">
        <DoubleAnimation.EasingFunction>
            <CircleEase EasingMode="EaseOut" />
        </DoubleAnimation.EasingFunction>
    </DoubleAnimation>
</Storyboard>

 

设置发光度从0到一,同时有叁个移动的意义。注意那里的StoryBoard.TargetProperty的写法,详细表明能够参照MSDN文书档案:

再度揶揄一下MSDN文档真是太难找了。版本太多。

在<VisualStateManager.VisualStateGroups>里添加Transitions:

<VisualStateGroup.Transitions>
    <VisualTransition From="NarrowAndNoBlankDetail" To="NarrowAndBlankDetail" ></VisualTransition>
</VisualStateGroup.Transitions>

 

与此同时要在gridMain里增添以下代码:

<Grid.RenderTransform>
    <CompositeTransform />
</Grid.RenderTransform>

 

不然动画不能够起效果。

于今运作一下看看,重回的时候MasterPage也是从右侧渐变滑入的,效果好了大多。

那种方式为主得以把WP8.一的代码直接拿过来用,页面退换相当小。即使您有更加好的兑现格局,欢迎留言探讨。

那篇基本就写到那里了。近年来WP圈一片哀嚎,许多无奈的事情。但作为一般民用开采者来讲,抱怨也没用,能做稍微就做稍微吧,总好过只调侃。行动的意义恒久大于口头空讲。

本文获得了礼品说开拓者郑大神的鼎力补助。希望大家下载她的赠礼说,做的万分精良。

预祝我们新岁欢腾!

谈到底给出demo下载:链接: 密码:ilar

 

图片 14

图片 14

  待项目创造实现后,解决方案共包蕴八个门类:共享代码项目、 Android
项目、 iOS 项目、 UWP
项目。共享代码项目为寄放共享页面包车型地铁地点,个人感觉和类库还是有点分别的。

  待项目开创完毕后,化解方案共包罗多少个门类:共享代码项目、 Android
项目、 iOS 项目、 UWP
项目。共享代码项目为寄放共享页面包车型大巴地点,个人感觉和类库还是有点分其他。

图片 16

图片 16

  

  

  三、共享代码项目
HamburgerMenu德姆o 

  三、共享代码项目
HamburgerMenu德姆o 

  首先增多多少个页面,根目录下增加3个 MasterPage.xaml
页面,用于”大纲视图“。增添八个 Views
文件夹,用于存放子页面,向在这之中加多二个分界面:Page1、Page二、Page三。增添一个 MasterPageItem.cs
类。

  首先增加几个页面,根目录下增多多个 MasterPage.xaml
页面,用于”大纲视图“。增多几个 Views
文件夹,用于存放子页面,向个中增添三个分界面:Page1、Page二、Page三。增添二个 MasterPageItem.cs
类。

  1. MasterPageItem.cs

  1. MasterPageItem.cs

  和 UWP 的波士顿菜单同样,首先要开创二个类,作为导航的花色,用来绑定
ListView 。名字叫 MasterPageItem.cs 。

  和 UWP 的奥斯陆菜单一样,首先要开创三个类,作为导航的门类,用来绑定
ListView 。名字叫 MasterPageItem.cs 。

  里面包车型地铁习性有页面包车型客车标题 Title,左边的Logo Icon,Logo的书体
FontFamily,指标页面 DestPage,还有左侧的矩形彰显 Selected 与 颜色
Color。由于要兑现双向绑定,还要完结接口 INotifyPropertyChanged。要留心的是,Color
类型为 Xamarin.Forms 中的。

  里面包车型大巴品质有页面包车型客车题目 Title,右侧的Logo Icon,Logo的字体
FontFamily,目标页面 DestPage,还有右边的矩形呈现 Selected 与 颜色
Color。由于要落到实处双向绑定,还要促成接口 INotifyPropertyChanged。要专注的是,Color
类型为 Xamarin.Forms 中的。

代码如下

代码如下

public class MasterPageItem : INotifyPropertyChanged
{
    // 字体路径,用于引入 Segoe MDL2 Assets 字体
    public string FontFamily { get; set; }

    // 字体图标转义
    public string Icon { get; set; }

    // 标题
    public string Title { get; set; }

    // 目的页
    public Type DestPage { get; set; }

    // 用于显示左侧填充矩形,双向绑定
    private bool selected = false;
    public bool Selected
    {
        get { return selected; }
        set
        {
            selected = value;
            this.OnPropertyChanged("Selected");
        }
    }

    // 选中颜色,双向绑定 ( using Xamarin.Forms )
    private Color color = new Color();
    public Color Color
    {
        get { return color; }
        set
        {
            color = value;
            this.OnPropertyChanged("Color");
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    public void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}
public class MasterPageItem : INotifyPropertyChanged
{
    // 字体路径,用于引入 Segoe MDL2 Assets 字体
    public string FontFamily { get; set; }

    // 字体图标转义
    public string Icon { get; set; }

    // 标题
    public string Title { get; set; }

    // 目的页
    public Type DestPage { get; set; }

    // 用于显示左侧填充矩形,双向绑定
    private bool selected = false;
    public bool Selected
    {
        get { return selected; }
        set
        {
            selected = value;
            this.OnPropertyChanged("Selected");
        }
    }

    // 选中颜色,双向绑定 ( using Xamarin.Forms )
    private Color color = new Color();
    public Color Color
    {
        get { return color; }
        set
        {
            color = value;
            this.OnPropertyChanged("Color");
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    public void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

  2. MasterPage.xaml

  2. MasterPage.xaml

  MasterPage 为”大纲“视图,即左边展现 ListView
的页面。本项指标 MasterPage 分为两栏,分一级菜单与二级菜单,即置顶1个ListView 与置底一个 ListView 。 ListView 的 ItemTemplate 与 UWP
稍有两样,左边的填写矩形换到了 BoxView,二级菜单的上面线由 Border
换来了冲天为一的 BoxView。代码如下

  MasterPage 为”大纲“视图,即左边浮现 ListView
的页面。本项指标 MasterPage 分为两栏,分一级菜单与二级菜单,即置顶二个ListView 与置底二个 ListView 。 ListView 的 ItemTemplate 与 UWP
稍有例外,左边的填充矩形换来了 BoxView,二级菜单的顶端线由 Border
换到了惊人为一的 BoxView。代码如下

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="HamburgerMenuDemo.MasterPage"
             Icon="hamburger.png"
             Title=" ">

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            <RowDefinition Height="1" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>

        <!--一级菜单-->
        <ListView x:Name="PrimaryListView" VerticalOptions="StartAndExpand" SeparatorVisibility="None">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <Grid HeightRequest="48">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="48"/>
                                <ColumnDefinition Width="*" />
                            </Grid.ColumnDefinitions>

                            <BoxView BackgroundColor="{Binding Color}" WidthRequest="5" HeightRequest="26" HorizontalOptions="Start" VerticalOptions="Center" IsVisible="{Binding Selected}" />
                            <Label Text="{Binding Icon}" FontFamily="{Binding FontFamily}" TextColor="{Binding Color}" FontSize="16" HorizontalOptions="Center" VerticalOptions="Center" />
                            <Label Grid.Column="1" Text="{Binding Title}" TextColor="{Binding Color}" FontSize="14" VerticalOptions="Center" />
                        </Grid>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>

        <!--BoxView 充当 Border-->
        <BoxView BackgroundColor="Gray" Grid.Row="1" HorizontalOptions="FillAndExpand" />

        <!--二级菜单-->
        <ListView x:Name="SecondaryListView" Grid.Row="2" VerticalOptions="End" SeparatorVisibility="None" Margin="0,-6,0,0">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <Grid HeightRequest="48">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="48"/>
                                <ColumnDefinition Width="*" />
                            </Grid.ColumnDefinitions>

                            <BoxView BackgroundColor="{Binding Color}" WidthRequest="5" HeightRequest="26" HorizontalOptions="Start" VerticalOptions="Center" IsVisible="{Binding Selected}" />
                            <Label x:Name="IconLabel" Text="{Binding Icon}" FontFamily="{Binding FontFamily}" TextColor="{Binding Color}" FontSize="16" HorizontalOptions="Center" VerticalOptions="Center" />
                            <Label Grid.Column="1" Text="{Binding Title}" TextColor="{Binding Color}" FontSize="14" VerticalOptions="Center" />
                        </Grid>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </Grid>
</ContentPage>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="HamburgerMenuDemo.MasterPage"
             Icon="hamburger.png"
             Title=" ">

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            <RowDefinition Height="1" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>

        <!--一级菜单-->
        <ListView x:Name="PrimaryListView" VerticalOptions="StartAndExpand" SeparatorVisibility="None">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <Grid HeightRequest="48">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="48"/>
                                <ColumnDefinition Width="*" />
                            </Grid.ColumnDefinitions>

                            <BoxView BackgroundColor="{Binding Color}" WidthRequest="5" HeightRequest="26" HorizontalOptions="Start" VerticalOptions="Center" IsVisible="{Binding Selected}" />
                            <Label Text="{Binding Icon}" FontFamily="{Binding FontFamily}" TextColor="{Binding Color}" FontSize="16" HorizontalOptions="Center" VerticalOptions="Center" />
                            <Label Grid.Column="1" Text="{Binding Title}" TextColor="{Binding Color}" FontSize="14" VerticalOptions="Center" />
                        </Grid>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>

        <!--BoxView 充当 Border-->
        <BoxView BackgroundColor="Gray" Grid.Row="1" HorizontalOptions="FillAndExpand" />

        <!--二级菜单-->
        <ListView x:Name="SecondaryListView" Grid.Row="2" VerticalOptions="End" SeparatorVisibility="None" Margin="0,-6,0,0">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <Grid HeightRequest="48">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="48"/>
                                <ColumnDefinition Width="*" />
                            </Grid.ColumnDefinitions>

                            <BoxView BackgroundColor="{Binding Color}" WidthRequest="5" HeightRequest="26" HorizontalOptions="Start" VerticalOptions="Center" IsVisible="{Binding Selected}" />
                            <Label x:Name="IconLabel" Text="{Binding Icon}" FontFamily="{Binding FontFamily}" TextColor="{Binding Color}" FontSize="16" HorizontalOptions="Center" VerticalOptions="Center" />
                            <Label Grid.Column="1" Text="{Binding Title}" TextColor="{Binding Color}" FontSize="14" VerticalOptions="Center" />
                        </Grid>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </Grid>
</ContentPage>

  MasterPage.xaml.cs 代码也急需讲下,不知是怎么回事,以上 Xaml
代码间接运维时七个菜单会议及展览示不健康,只展现多个菜谱,<RowDefinition
Height=”Auto” /> 在那么些 ContentPage
里好像无效。因而笔者在后台代码设置了二级菜单的万丈,也正是4八 *
secondaryItems.Count。四个 ListView 须要经过质量的主意,向 MainPage
传递控件。字体路线各样项目不相同,须求独自设置,笔者背后会说。MasterPage.xaml.cs
代码如下

  MasterPage.xaml.cs 代码也亟需讲下,不知是怎么回事,以上 Xaml
代码直接运转时八个菜单会议及展览示不常常,只展现3个美食做法,<RowDefinition
Height=”Auto” /> 在那些 ContentPage
里好像无效。由此笔者在后台代码设置了二级菜单的莫斯中国科学技术大学学,相当于48 *
secondaryItems.Count。多少个 ListView 须求经过质量的点子,向 MainPage
传递控件。字体路线各样品种差别,必要单独设置,笔者背后会说。MasterPage.xaml.cs
代码如下

[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class MasterPage : ContentPage
{
    // 向 MainPage 传递控件
    public ListView primaryListView { get { return PrimaryListView; } }
    public ListView secondaryListView { get { return SecondaryListView; } }

    public MasterPage()
    {
        InitializeComponent();

        // 设置不同平台的字体路径
        string fontFamily;
        switch (Device.RuntimePlatform)
        {
            case "Android":
                fontFamily = "segmdl2.ttf#Segoe MDL2 Assets";
                break;

            case "iOS":
                fontFamily = "Segoe MDL2 Assets";
                break;

            case "Windows":
                fontFamily = "/Assets/segmdl2.ttf#Segoe MDL2 Assets";
                break;

            case "WinPhone":
                fontFamily = "/Assets/segmdl2.ttf#Segoe MDL2 Assets";
                break;

            default:
                fontFamily = "segmdl2.ttf#Segoe MDL2 Assets";
                break;
        }

        // 列表项
        var primaryItems = new List<MasterPageItem>() {
                new MasterPageItem
                {
                    Title = "Page1",
                    FontFamily = fontFamily,
                    Icon = "\xE10F",
                    Color = Color.DeepSkyBlue,
                    Selected = true,
                    DestPage = typeof(Page1)
                },
                new MasterPageItem
                {
                    Title = "Page2",
                    FontFamily = fontFamily,
                    Icon = "\xE11F",
                    Color = Color.Black,
                    Selected = false,
                    DestPage = typeof(Page2)
                },
                new MasterPageItem
                {
                    Title = "Page3",
                    FontFamily = fontFamily,
                    Icon = "\xE12F",
                    Color = Color.Black,
                    Selected = false,
                    DestPage = typeof(Page2)
                }
            };

        var secondaryItems = new List<MasterPageItem>() {
                new MasterPageItem
                {
                    Title = "设置",
                    FontFamily = fontFamily,
                    Icon = "\xE713",
                    Color = Color.Black,
                    Selected = false,
                    DestPage = typeof(SettingPage)
                },
                new MasterPageItem
                {
                    Title = "关于",
                    FontFamily = fontFamily,
                    Icon = "\xE783",
                    Color = Color.Black,
                    Selected = false,
                    DestPage = typeof(AboutPage)
                }
            };

        // ListView 数据绑定
        PrimaryListView.ItemsSource = primaryItems;
        SecondaryListView.ItemsSource = secondaryItems;

        // 设置二级菜单高度
        SecondaryListView.HeightRequest = 48 * secondaryItems.Count;
    }
}
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class MasterPage : ContentPage
{
    // 向 MainPage 传递控件
    public ListView primaryListView { get { return PrimaryListView; } }
    public ListView secondaryListView { get { return SecondaryListView; } }

    public MasterPage()
    {
        InitializeComponent();

        // 设置不同平台的字体路径
        string fontFamily;
        switch (Device.RuntimePlatform)
        {
            case "Android":
                fontFamily = "segmdl2.ttf#Segoe MDL2 Assets";
                break;

            case "iOS":
                fontFamily = "Segoe MDL2 Assets";
                break;

            case "Windows":
                fontFamily = "/Assets/segmdl2.ttf#Segoe MDL2 Assets";
                break;

            case "WinPhone":
                fontFamily = "/Assets/segmdl2.ttf#Segoe MDL2 Assets";
                break;

            default:
                fontFamily = "segmdl2.ttf#Segoe MDL2 Assets";
                break;
        }

        // 列表项
        var primaryItems = new List<MasterPageItem>() {
                new MasterPageItem
                {
                    Title = "Page1",
                    FontFamily = fontFamily,
                    Icon = "\xE10F",
                    Color = Color.DeepSkyBlue,
                    Selected = true,
                    DestPage = typeof(Page1)
                },
                new MasterPageItem
                {
                    Title = "Page2",
                    FontFamily = fontFamily,
                    Icon = "\xE11F",
                    Color = Color.Black,
                    Selected = false,
                    DestPage = typeof(Page2)
                },
                new MasterPageItem
                {
                    Title = "Page3",
                    FontFamily = fontFamily,
                    Icon = "\xE12F",
                    Color = Color.Black,
                    Selected = false,
                    DestPage = typeof(Page2)
                }
            };

        var secondaryItems = new List<MasterPageItem>() {
                new MasterPageItem
                {
                    Title = "设置",
                    FontFamily = fontFamily,
                    Icon = "\xE713",
                    Color = Color.Black,
                    Selected = false,
                    DestPage = typeof(SettingPage)
                },
                new MasterPageItem
                {
                    Title = "关于",
                    FontFamily = fontFamily,
                    Icon = "\xE783",
                    Color = Color.Black,
                    Selected = false,
                    DestPage = typeof(AboutPage)
                }
            };

        // ListView 数据绑定
        PrimaryListView.ItemsSource = primaryItems;
        SecondaryListView.ItemsSource = secondaryItems;

        // 设置二级菜单高度
        SecondaryListView.HeightRequest = 48 * secondaryItems.Count;
    }
}

  3. MainPage.xaml

  3. MainPage.xaml

  下边来修改一下 MainPage.xaml 。MainPage.xaml 为使用的输入页面,可在
App.xaml.cs 中改动。将 MainPage 中的根成分替换为 MasterDetailPage
。注释很详细,不多说了

  上面来修改一下 MainPage.xaml 。MainPage.xaml 为利用的进口页面,可在
App.xaml.cs 中改变。将 MainPage 中的根成分替换为 MasterDetailPage
。注释很详细,不多说了

<MasterDetailPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:HamburgerMenuDemo"
             x:Class="HamburgerMenuDemo.MainPage"
             xmlns:views="clr-namespace:HamburgerMenuDemo.Views">

    <!--大纲视图-->
    <MasterDetailPage.Master>
        <!--引入 MasterPage 并给个名称,用于后台设置 MasterPage 传递过来的 ListView-->
        <local:MasterPage x:Name="masterPage" />
    </MasterDetailPage.Master>

    <!--细节视图-->
    <MasterDetailPage.Detail>
        <NavigationPage>
            <x:Arguments>
                <!--默认显示的页面-->
                <views:Page1 />
            </x:Arguments>
        </NavigationPage>
    </MasterDetailPage.Detail>

</MasterDetailPage>
<MasterDetailPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:HamburgerMenuDemo"
             x:Class="HamburgerMenuDemo.MainPage"
             xmlns:views="clr-namespace:HamburgerMenuDemo.Views">

    <!--大纲视图-->
    <MasterDetailPage.Master>
        <!--引入 MasterPage 并给个名称,用于后台设置 MasterPage 传递过来的 ListView-->
        <local:MasterPage x:Name="masterPage" />
    </MasterDetailPage.Master>

    <!--细节视图-->
    <MasterDetailPage.Detail>
        <NavigationPage>
            <x:Arguments>
                <!--默认显示的页面-->
                <views:Page1 />
            </x:Arguments>
        </NavigationPage>
    </MasterDetailPage.Detail>

</MasterDetailPage>

  同样的 MainPage.xaml.cs 中的代码也异常的粗略,注释很详细

  同样的 MainPage.xaml.cs 中的代码也相当的粗略,注释很详细

public MainPage()
{
    InitializeComponent();

    // ListView 点击事件
    masterPage.primaryListView.ItemSelected += MasterPageItemSelected;
    masterPage.secondaryListView.ItemSelected += MasterPageItemSelected;

    // 设置 Windows 平台的“大纲”显示模式为折叠
    if (Device.RuntimePlatform == Device.Windows)
    {
        MasterBehavior = MasterBehavior.Popover;
    }
}

private void MasterPageItemSelected(object sender, SelectedItemChangedEventArgs e)
{
    var item = e.SelectedItem as MasterPageItem;

    if (item != null)
    {
        // 遍历 ListView 数据源,将选中项矩形显示,字体颜色设置成未选中
        foreach (MasterPageItem mpi in masterPage.primaryListView.ItemsSource)
        {
            mpi.Selected = false;
            mpi.Color = Color.Black;
        }
        foreach (MasterPageItem mpi in masterPage.secondaryListView.ItemsSource)
        {
            mpi.Selected = false;
            mpi.Color = Color.Black;
        }

        // 设置选中项
        item.Selected = true;
        item.Color = Color.DeepSkyBlue;

        // 跳转
        Detail = new NavigationPage((Page)Activator.CreateInstance(item.DestPage));

        // 取消 ListView 默认选中样式
        masterPage.primaryListView.SelectedItem = null;
        masterPage.secondaryListView.SelectedItem = null;

        // 关闭“大纲”
        IsPresented = false;
    }
}
public MainPage()
{
    InitializeComponent();

    // ListView 点击事件
    masterPage.primaryListView.ItemSelected += MasterPageItemSelected;
    masterPage.secondaryListView.ItemSelected += MasterPageItemSelected;

    // 设置 Windows 平台的“大纲”显示模式为折叠
    if (Device.RuntimePlatform == Device.Windows)
    {
        MasterBehavior = MasterBehavior.Popover;
    }
}

private void MasterPageItemSelected(object sender, SelectedItemChangedEventArgs e)
{
    var item = e.SelectedItem as MasterPageItem;

    if (item != null)
    {
        // 遍历 ListView 数据源,将选中项矩形显示,字体颜色设置成未选中
        foreach (MasterPageItem mpi in masterPage.primaryListView.ItemsSource)
        {
            mpi.Selected = false;
            mpi.Color = Color.Black;
        }
        foreach (MasterPageItem mpi in masterPage.secondaryListView.ItemsSource)
        {
            mpi.Selected = false;
            mpi.Color = Color.Black;
        }

        // 设置选中项
        item.Selected = true;
        item.Color = Color.DeepSkyBlue;

        // 跳转
        Detail = new NavigationPage((Page)Activator.CreateInstance(item.DestPage));

        // 取消 ListView 默认选中样式
        masterPage.primaryListView.SelectedItem = null;
        masterPage.secondaryListView.SelectedItem = null;

        // 关闭“大纲”
        IsPresented = false;
    }
}

  要留意的是 MasterPage.xaml 页面中的 Title
一定要给,要否则会报错,能够在后台 cs 文件中期维修改 Title 属性,也能够在
Xaml 根成分中期维修改 Title。Views 中的多少个页面 Title
不给能够,但标题栏不会议及展览示页面包车型大巴 Title,不佳看。

  要留意的是 MasterPage.xaml 页面中的 Title
一定要给,要不然会报错,可以在后台 cs 文件中期维修改 Title 属性,也得以在
Xaml 根成分中期维修改 Title。Views 中的多少个页面 Title
不给能够,但标题栏不会显得页面包车型大巴 Title,不佳看。

 

 

  四、Android
项目 HamburgerMenuDemo.Android

  四、Android
项目 HamburgerMenuDemo.Android

  一. 字体设置

  一. 字体设置

  将 segmdl2.ttf 字体文件一直放入 Assets 文件夹下就能够

  将 segmdl2.ttf 字体文件直接放入 Assets 文件夹下就可以

  2. 修改 style.xml

  2. 修改 style.xml

  ”大纲“的默许效果是 DrawerLayout
覆盖状态栏的,不太美貌,需求修改样式。在 style.xml 中增加

  ”大纲“的暗中认可效果是 DrawerLayout
覆盖状态栏的,不太美丽,须求修改样式。在 style.xml 中增加

<item name="android:fitsSystemWindows">true</item>
<item name="android:fitsSystemWindows">true</item>

  同时,由于修改了体制,形成了状态栏覆盖 DrawerLayout
,须要给 MasterPage.xaml 中的根 Grid 赋值3个 Padding=”0,25,0,-六”,但
UWP 项目却不要求,这一点小编会在文末给出代码。

  同时,由于修改了体制,形成了状态栏覆盖 DrawerLayout
,必要给 MasterPage.xaml 中的根 Grid 赋值三个 Padding=”0,25,0,-6″,但
UWP 项目却不需求,那一点作者会在文末给出代码。

 

 

  五、iOS
项目 HamburgerMenuDemo.iOS

  五、iOS
项目 HamburgerMenuDemo.iOS

  1. 字体设置

  壹. 字体设置

  弄了长期,Xamarin 太坑了,plist 的编辑器很不协调。。。

  弄了永久,Xamarin 太坑了,plist 的编辑器很不协调。。。

  (壹)将 segmdl2.ttf 字体文件间接放入 Resources 文件夹

  (一)将 segmdl二.ttf 字体文件一贯放入 Resources 文件夹

  (2)改变 segmdl2.ttf 属性,复制到输出目录 =》 始终复制,生成操作
=》 BundleResource

  (二)改换 segmdl二.ttf 属性,复制到输出目录 =》 始终复制,生成操作
=》 BundleResource

  (二)不要双击,右击 Info.plist ,查看代码,加多如下内容

  (二)不要双击,右击 Info.plist ,查看代码,增加如下内容

<dict>
    <key>UIAppFonts</key>
    <array>
      <string>segmdl2.ttf</string>
    </array>
  </dict>
<dict>
    <key>UIAppFonts</key>
    <array>
      <string>segmdl2.ttf</string>
    </array>
  </dict>

  假如要增加其余的能源,能够本人新建1个 .plist
文件,新建的文件是不荒谬展现财富列表的,增多完毕后,复制代码到 Info.plist
就能够。

  倘使要增添任何的能源,能够协调新建1个 .plist
文件,新建的文书是平常展现财富列表的,加多完结后,复制代码到 Info.plist
就可以。

  2. Padding

  2. Padding

  和安卓一律,供给给 MasterPage.xaml 中的根 Grid 赋值贰个Padding=”0,20,0,-6″,小编会在文末给出代码。

  和安卓同样,须求给 MasterPage.xaml 中的根 Grid 赋值多少个Padding=”0,20,0,-陆”,笔者会在文末给出代码。

 

 

  六、Padding 代码

  六、Padding 代码

  在 MasterPage.xaml 加多如下代码

  在 MasterPage.xaml 增多如下代码

<!--安卓空出状态栏的宽度-->
<ContentPage.Resources>
    <ResourceDictionary>
        <OnPlatform x:Key="padding"
              x:TypeArguments="Thickness"
              iOS="0,20,0,-6"
              Android="0,25,0,-6"
              WinPhone="0" />
    </ResourceDictionary>
</ContentPage.Resources>
<!--安卓空出状态栏的宽度-->
<ContentPage.Resources>
    <ResourceDictionary>
        <OnPlatform x:Key="padding"
              x:TypeArguments="Thickness"
              iOS="0,20,0,-6"
              Android="0,25,0,-6"
              WinPhone="0" />
    </ResourceDictionary>
</ContentPage.Resources>

  别忘了在 Grid 中援引进资金源

  别忘了在 Grid 中援引进资金源

Padding="{StaticResource padding}"
Padding="{StaticResource padding}"

  MasterPage.xaml 最后代码

  MasterPage.xaml 最后代码

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="HamburgerMenuDemo.MasterPage"
             Icon="hamburger.png"
             Title=" ">

    <!--安卓空出状态栏的宽度-->
    <ContentPage.Resources>
        <ResourceDictionary>
            <OnPlatform x:Key="padding"
                  x:TypeArguments="Thickness"
                  iOS="0,20,0,0"
                  Android="0,20,0,0"
                  WinPhone="0" />
        </ResourceDictionary>
    </ContentPage.Resources>

    <Grid Padding="{StaticResource padding}">
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            <RowDefinition Height="1" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>

        <!--一级菜单-->
        <ListView x:Name="PrimaryListView" VerticalOptions="StartAndExpand" SeparatorVisibility="None">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <Grid HeightRequest="48">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="48"/>
                                <ColumnDefinition Width="*" />
                            </Grid.ColumnDefinitions>

                            <BoxView BackgroundColor="{Binding Color}" WidthRequest="5" HeightRequest="26" HorizontalOptions="Start" VerticalOptions="Center" IsVisible="{Binding Selected}" />
                            <Label Text="{Binding Icon}" FontFamily="{Binding FontFamily}" TextColor="{Binding Color}" FontSize="16" HorizontalOptions="Center" VerticalOptions="Center" />
                            <Label Grid.Column="1" Text="{Binding Title}" TextColor="{Binding Color}" FontSize="14" VerticalOptions="Center" />
                        </Grid>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>

        <!--BoxView 充当 Border-->
        <BoxView BackgroundColor="Gray" Grid.Row="1" HorizontalOptions="FillAndExpand" />

        <!--二级菜单-->
        <ListView x:Name="SecondaryListView" Grid.Row="2" VerticalOptions="End" SeparatorVisibility="None" Margin="0,-6,0,0">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <Grid HeightRequest="48">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="48"/>
                                <ColumnDefinition Width="*" />
                            </Grid.ColumnDefinitions>

                            <BoxView BackgroundColor="{Binding Color}" WidthRequest="5" HeightRequest="26" HorizontalOptions="Start" VerticalOptions="Center" IsVisible="{Binding Selected}" />
                            <Label x:Name="IconLabel" Text="{Binding Icon}" FontFamily="{Binding FontFamily}" TextColor="{Binding Color}" FontSize="16" HorizontalOptions="Center" VerticalOptions="Center" />
                            <Label Grid.Column="1" Text="{Binding Title}" TextColor="{Binding Color}" FontSize="14" VerticalOptions="Center" />
                        </Grid>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </Grid>
</ContentPage>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="HamburgerMenuDemo.MasterPage"
             Icon="hamburger.png"
             Title=" ">

    <!--安卓空出状态栏的宽度-->
    <ContentPage.Resources>
        <ResourceDictionary>
            <OnPlatform x:Key="padding"
                  x:TypeArguments="Thickness"
                  iOS="0,20,0,0"
                  Android="0,20,0,0"
                  WinPhone="0" />
        </ResourceDictionary>
    </ContentPage.Resources>

    <Grid Padding="{StaticResource padding}">
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            <RowDefinition Height="1" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>

        <!--一级菜单-->
        <ListView x:Name="PrimaryListView" VerticalOptions="StartAndExpand" SeparatorVisibility="None">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <Grid HeightRequest="48">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="48"/>
                                <ColumnDefinition Width="*" />
                            </Grid.ColumnDefinitions>

                            <BoxView BackgroundColor="{Binding Color}" WidthRequest="5" HeightRequest="26" HorizontalOptions="Start" VerticalOptions="Center" IsVisible="{Binding Selected}" />
                            <Label Text="{Binding Icon}" FontFamily="{Binding FontFamily}" TextColor="{Binding Color}" FontSize="16" HorizontalOptions="Center" VerticalOptions="Center" />
                            <Label Grid.Column="1" Text="{Binding Title}" TextColor="{Binding Color}" FontSize="14" VerticalOptions="Center" />
                        </Grid>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>

        <!--BoxView 充当 Border-->
        <BoxView BackgroundColor="Gray" Grid.Row="1" HorizontalOptions="FillAndExpand" />

        <!--二级菜单-->
        <ListView x:Name="SecondaryListView" Grid.Row="2" VerticalOptions="End" SeparatorVisibility="None" Margin="0,-6,0,0">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <Grid HeightRequest="48">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="48"/>
                                <ColumnDefinition Width="*" />
                            </Grid.ColumnDefinitions>

                            <BoxView BackgroundColor="{Binding Color}" WidthRequest="5" HeightRequest="26" HorizontalOptions="Start" VerticalOptions="Center" IsVisible="{Binding Selected}" />
                            <Label x:Name="IconLabel" Text="{Binding Icon}" FontFamily="{Binding FontFamily}" TextColor="{Binding Color}" FontSize="16" HorizontalOptions="Center" VerticalOptions="Center" />
                            <Label Grid.Column="1" Text="{Binding Title}" TextColor="{Binding Color}" FontSize="14" VerticalOptions="Center" />
                        </Grid>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </Grid>
</ContentPage>

 

 

相关文章