多个AppBar / CommandBar

时间:2014-04-20 06:15:01

标签: c# xaml windows-phone-8.1

回到Windows Phone 8,我能够使用多个AppBar,在某些数据透视页面上交换它们,但在Windows Phone 8.1中,我不知道该怎么做或者这甚至可能。

基本上对于我的场景,我有3个Pivot页面。每个页面都需要有一个不同的CommandBar,因为它需要有不同的控件。

是否有人能告诉我如何做到这一点?

修改 我用于Windows Phone 8的代码执行此操作:

XAML:

<phone:PhoneApplicationPage.Resources>
<shell:ApplicationBar x:Key="AppBar1" IsVisible="True" IsMenuEnabled="True">
    <shell:ApplicationBarIconButton IconUri="/Images/appbar_button1.png" Text="Button 1"/>
    <shell:ApplicationBar.MenuItems>
        <shell:ApplicationBarMenuItem Text="MenuItem 1"/>
    </shell:ApplicationBar.MenuItems>
</shell:ApplicationBar>

<shell:ApplicationBar x:Key="AppBar2" IsVisible="True" IsMenuEnabled="True">
    <shell:ApplicationBarIconButton IconUri="/Images/appbar_button1.png" Text="Button 1" />
    <shell:ApplicationBarIconButton IconUri="/Images/appbar_button2.png" Text="Button 2" />
    <shell:ApplicationBar.MenuItems>
        <shell:ApplicationBarMenuItem Text="MenuItem 1" />
        <shell:ApplicationBarMenuItem Text="MenuItem 2" />
    </shell:ApplicationBar.MenuItems>
</shell:ApplicationBar>

C#:

private void MainPivot_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        switch (MainPivot.SelectedIndex)
        {
            case 0:
                ApplicationBar = this.Resources["AppBar1"] as ApplicationBar;
                break;
            case 1:
                ApplicationBar = this.Resources["AppBar2"] as ApplicationBar;
                break;
        }
    }

基本上在更改数据透视表时切换AppBar。

3 个答案:

答案 0 :(得分:14)

一个简单的解决方案是使用XAML定义按钮和ViewModel(MVVM模式)来控制这些按钮的可见性,这可以避免在代码中创建按钮和复杂的逻辑来控制显示哪个按钮。

首先,定义CommandBar中可能使用的所有按钮:

<Page.BottomAppBar>
    <CommandBar>
        <!--buttons of group1-->
        <AppBarButton Icon="Icon1" Label="button1"/>
        ...
        <!--buttons of group2-->
        <AppBarButton Icon="Icon2" Label="button2"/>
        ...
        <!--buttons of group3-->
        <AppBarButton Icon="Icon3" Label="button3"/>
    </CommandBar>
</Page.BottomAppBar>

然后在ViewModel中定义一个属性,例如:

public class PageViewModel : INotifyPropertyChanged
{
    ...
    public int CommandGroup
    {
        get { return _commandGroup; }
        set { _commandGroup = value; NotifyPropertyChanged("CommandGroup"); }
    }
}

CommandGroup 属性用于控制按钮的显示/隐藏,例如,设置CommandGroup = 1以显示group1中的按钮并隐藏其他组中的按钮,并将CommandGroup = 2设置为show group2中的按钮和其他组中的隐藏按钮,其中group1和group2只是逻辑组。

然后定义转换器以将CommandGroup属性的值转换为Visibility:

public class CommandGroupToVisibilityConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language) 
    {
        return (System.Convert.ToInt32(value) == System.Convert.ToInt32(parameter)) ? Visibility.Visible : Visibility.Collapsed;
    }
}

最后,将此CommandGroup属性绑定到CommandBar中的所有按钮(复制和粘贴内容):

<Page.Resources>
    <c:CommandGroupToVisibilityConverter x:Key="MyConverter"/>
</Page.Resources>
<Page.BottomAppBar>
    <CommandBar>
        <!--buttons of group1-->
        <AppBarButton 
            Icon="Icon1" Label="button1" 
            Visibility="{Binding CommandGroup, Converter={StaticResource MyConverter}, ConverterParameter=1}"/>

        <!--buttons of group2-->
        <AppBarButton 
            Icon="Icon2" Label="button2" 
            Visibility="{Binding CommandGroup, Converter={StaticResource MyConverter}, ConverterParameter=2}"/>

        <!--buttons of group3-->
        <AppBarButton 
            Icon="Icon3" Label="button3" 
            Visibility="{Binding CommandGroup, Converter={StaticResource MyConverter}, ConverterParameter=3}"/>
    </CommandBar>
</Page.BottomAppBar>

请注意,当CommandGroup == 2时,将显示所有具有ConverterParameter = 2的按钮,其他按钮将消失。

在一个页面中有多个视图(如Pivot)并且每个视图都有不同的命令按钮组时,这可能非常有用。

答案 1 :(得分:13)

在WP8.1 RT中,您有一个属性BottomAppBar of your Page。它与旧的ApplicationBar几乎相同(除了扩展) - 您可以使用CommandBar进行设置。我已经在代码中创建了我的命令栏并且它可以工作,你可以尝试这样:

// prepare your CommandBars - run method somewhere in the constructor of the page:
CommandBar firstBar;
CommandBar secondBar;

private void PrepareAppBars()
{
    firstBar = new CommandBar();
    firstBar.IsOpen = true;
    AppBarButton FirstBtn = new AppBarButton() { Icon = new BitmapIcon() { UriSource = new Uri("ms-appx:///Assets/first.png") } };
    FirstBtn.Label = "First";
    FirstBtn.Click += FirstBtn_Click;
    FirstBtn.IsEnabled = true;
    // Similar for second button
    AppBarButton SecondBtn = new AppBarButton() { Icon = new BitmapIcon() { UriSource = new Uri("ms-appx:///Assets/second.png") } };

    firstBar.PrimaryCommands.Add(FirstBtn);
    firstBar.PrimaryCommands.Add(SecondBtn);

    // define also SecondaryCommands

    // simlar secondBar
    secondBar = new CommandBar();
    secondBar.IsOpen = true;
    // ...
}

// then you can surely switch them like this:

private void MainPivot_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    switch (MainPivot.SelectedIndex)
    {
        case 0:
            BottomAppBar = firstBar ;
            break;
        case 1:
            BottomAppBar = secondBar ;
            break;
    }
}

答案 2 :(得分:1)

我最终创建了我的基页类(实际上我已经将我的导航参数传递给ViewModel),它扩展了原始页面。在Base Page中我添加了Dependency Property AppBarCollection,以便我可以在Xaml的真实页面中使用它。在那里,我定义了所有必要的AppBars,而无需在后面的代码中创建它们。我在那里做的唯一一件事是选择展示哪一个。即使这可以从Xaml完成,但我并不想让事情变得更复杂。 该选项基本上是第一个建议,区别在于您可以在xaml中定义您页面中的所有AppBars。

<views:BindablePage.AppBarCollection>
    <views:AppBarCollection>
        <CommandBar/>
        <CommandBar/>
        <CommandBar/>
    </views:AppBarCollection>
</views:BindablePage.AppBarCollection>