0
votes

I've been trying to implement Microsoft's hamburger pattern in my own way for some time.

Final result was the following:

  • AppShell for containing current page and hamburger menu (menu always visible)
  • In Appshell, Grid with two rows: one 48px in height, one one-start height.
  • In first row, added a commandbar (global), and hamburger button (togglebutton with custom style for being 48px wide and tall, with the hamburger fonticon in the center)
  • In second row, SplitView with a ListBox on the Pane, and a Frame in the Content.

This way one has control over the content, while displaying a global menu and command bar. On the Navigated event of the Frame, I update the CommandBar to pull the primary and secondary commands from the Frame's Content's properties (I use a custom page control with those properties), and the content of the CommandBar (which is, of now, a single TextBlock with binding).

However, I wanted to move the ToggleButton into the CommandBar. It worked nicely, except the binding (IsChecked of ToggleButton is bound to IsPaneOpen of SplitView) does not work. I use the regular ElementName targeting, and would prefer to not to use a ViewModel property.

Does the CommandBar.Content use a different context? Or why doesn't the ElementName reference work?

3
do you use x:Bind ? have you set the Mode property correctly?Markus Hütter
I use regular Binding, not x:Bind. Mode is set properly (TwoWay), but it's like the property change never fires. If I copy-paste the exact code of the ToggleButton out of the CommandBar, it works fine. If inside the Content of the Commandbar, it stops working.fonix232
have you tried reversing the binding? What I mean by that is: Instead of having a two way binding on the ToggleButton have a one-way binding like IsPaneOpen="{Binding IsChecked, ElementName=Toggle}"Markus Hütter
Yes I did, with similar result. It's like the control in the CommandBar content does not exist. Funny thing though - I bind a TextBlock's Text to the Frame's Content's Title property (I use a custom Page control), and THAT works.fonix232

3 Answers

0
votes

Only way, how I was able to bind to AppBarToggleButton was to set the DataContext in the code behind.

XAML:

<Page.BottomAppBar>
  <CommandBar x:Name="CommandBar">
    <AppBarToggleButton x:Name="Button" IsChecked="{Binding IsPaneOpen, Mode=TwoWay}" Icon="Home" Label="Button"/>
  </CommandBar>
</Page.BottomAppBar>

Code behind:

protected override void OnNavigatedTo(NavigationEventArgs e)
{
  base.OnNavigatedTo(e);
  Button.DataContext = SplitView;
}
0
votes

This works for me:

<Page
    x:Class="StackOverflowTests.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="48"/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <CommandBar>
            <CommandBar.Content>
                <AppBarToggleButton Icon="Globe" IsChecked="{Binding ElementName=SplitView,Path=IsPaneOpen,Mode=TwoWay}"/>
            </CommandBar.Content>
        </CommandBar>
        <SplitView Grid.Row="1" Name="SplitView" IsPaneOpen="{x:Bind Appbarbutton.IsChecked.Value,Mode=OneWay}">
            <SplitView.Pane>
                <ListBox>
                    <ListBoxItem>Foo</ListBoxItem>
                    <ListBoxItem>Bar</ListBoxItem>
                </ListBox>
            </SplitView.Pane>
            <SplitView.Content>
                <TextBlock>stuff here</TextBlock>
            </SplitView.Content>
        </SplitView>
    </Grid>
    <Page.BottomAppBar>
        <CommandBar>
            <CommandBar.Content>
                <AppBarToggleButton Name="Appbarbutton" Icon="Home" />
            </CommandBar.Content>
        </CommandBar>
    </Page.BottomAppBar>
</Page>
0
votes

You have bind DataContext: Example:

<Page.BottomAppBar >
    <CommandBar x:Name="commandBar" DataContext="{Binding}">
        <CommandBar.Content>
            <StackPanel Margin="0,0">
                <ListView ItemsSource="{Binding Confirmation.AvailableValues}" ItemContainerStyle="{StaticResource ListViewItemBase}">
                    <ListView.ItemTemplate>
                        <DataTemplate>
                            <Button Content="{Binding Value.DisplayName}" Command="{Binding DataContext.Confirm, ElementName=commandBar}" CommandParameter="{Binding Value}" HorizontalAlignment="Center"></Button>
                        </DataTemplate>
                    </ListView.ItemTemplate>
                </ListView>
                <Line Margin="5" X1="0" X2="1000" Y1="0" Y2="0" HorizontalAlignment="Stretch" Height="2"  Stroke="#888888"   StrokeThickness="1" ></Line>
            </StackPanel>
        </CommandBar.Content>
    </CommandBar>

</Page.BottomAppBar>