Binding the visibility of app bar buttons to controls - c#

I have a very simple Windows Phone 8.1 app. This app has two screens, and for simplicity's sake and because I have some common functions, I've implemented both of these screens within MainPage.xaml. I want to bind the visibility of the AppBar buttons to these screens / panels. Here's what I tried
<Page.BottomAppBar>
<CommandBar>
<CommandBar.PrimaryCommands>
<AppBarButton Icon="Add" IsCompact="False" Visibility="{Binding ElementName=ViewItemsPanel, Path=Visibility}" Label="Add" Click="AddButton_Click" />
<AppBarButton Icon="Cancel" IsCompact="False" Visibility="{Binding ElementName=EditItemPanel, Path=Visibility}" Label="Cancel" Click="CancelButton_Click" />
<AppBarButton Icon="Save" IsCompact="False" Visibility="{Binding ElementName=EditItemPanel, Path=Visibility}" Label="Save" Click="SaveButton_Click" />
</CommandBar.PrimaryCommands>
<CommandBar.SecondaryCommands>
</CommandBar.SecondaryCommands>
</CommandBar>
</Page.BottomAppBar>
Unfortunately this doesn't work - all three buttons are visible on both screens. I could create a dynamic property in code-behind for each of these but I thought there might be a nice elegant way to do something like this - is it possible?

The AppBar isn't in the same namespace as the page and so the bindings to the page's elements resolve. This is the case for any binding of the AppBar to the page.
You can set the AppBar's DataContext to the page in the page Loaded event and then bind to properties on the page.

you could create a grid panel to mimic the app bar, name the grid drop the app bar buttons in it and collapse or make visible as needed. Might not be the most elegant way to do it but it will get the job done.

You can create several app bars in your code behind and set the ApplicationBar property of you page to the appbar you like to display.
I used this solution in a pivot view with 3 pages
var applicationBars = new List<Microsoft.Phone.Shell.ApplicationBar>();
private void MainPivot_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
switch (mainPivot.SelectedIndex)
{
case 0: ApplicationBar = applicationBars[0]; break;
case 1: ApplicationBar = applicationBars[1]; break;
case 2: ApplicationBar = applicationBars[2]; break;
...
}
}

Related

Windows 10 UWP Command Bar

Since applying the Windows 10 Anniversary Edition along with the SDK, one of the Command Bars has different behavior. It used to display three AppButtons. Now, only two will display. There appears to be an empty button on the far left.
Here is the XAML:
<CommandBar x:Name="VideoGroupCommands"
RelativePanel.AlignBottomWithPanel="True"
RelativePanel.AlignLeftWithPanel="True"
RelativePanel.AlignRightWithPanel="True"
Background="{StaticResource LightBeigeBrush}"
IsEnabled="{x:Bind ViewModel.IsVideoGroupSelected,Mode=TwoWay}">
<AppBarButton Icon="Edit"
x:Uid="Edit"
Label=""
Command="{x:Bind ViewModel.EditVideoGroupCommand}"/>
<AppBarButton Icon="Delete"
x:Uid="Delete"
Label=""
Command="{x:Bind ViewModel.DeleteGroupCommand}"/>
<AppBarButton Icon="MoveToFolder" x:Uid="Merge" Label=""/>
</CommandBar>
How do I eliminate the gap on the left?
I believe the update changed the display mechanics, slightly, for the command bar. To fix this, I changed the grid column the control is in from a FIXED width to an AUTO width. Now, the control displays all three buttons with no gap on the left. The column is a little wider, but I can absorb it.
In the picture above, the command bar was cutting the third button out of the display.

Popup overlaps application bar

I'm trying to show a fullscreen popup along with application bar. To do this I'm using such code:
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Button Name="myButton" Content="Show PopUP" Click="myButton_Click"/>
<Popup x:Name="myPopup">
<Grid Name="PopupsGrid" Background="ForestGreen">
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Text="This is my PopUp"/>
</Grid>
</Popup>
</Grid>
<Page.BottomAppBar>
<CommandBar>
<AppBarButton Label="Done" Icon="Setting"/>
<CommandBar.SecondaryCommands>
<AppBarButton Label="Command"/>
</CommandBar.SecondaryCommands>
</CommandBar>
</Page.BottomAppBar>
private void myButton_Click(object sender, RoutedEventArgs e)
{
var bounds = Windows.UI.ViewManagement.ApplicationView.GetForCurrentView().VisibleBounds;
PopupsGrid.Height = bounds.Height - 25; // to show the problem - normally we can substract BottomAppBar.Height
PopupsGrid.Width = bounds.Width;
myPopup.IsOpen = true;
}
I've figured out that we can use ApplicationView.GetForCurrentView().VisibleBounds to calculate the desired height. So far so good, but when I open the popup it overlaps the application bar (see picture 2). On the other hand once we open the appbar, it seems to be overlapped partially (see picture 3).
I've tested it both on desktop and mobile and the same problem occurs.
Am I missing something? How to put application bar above popup?
I don't think we can make sure commandbar is always above the popup. The popup command you saw in the third screenshot is actually a popup control so it can be above "myPopup" in this scenario. But, if you set the commandbar's IsSticky and IsOpen to true, when you click the button to show popup, it will hide the popup command. Popups follows this rule: latest on the top.
For the "overlapped partially" issue, instead of making the popup full screen, I think we can dynamically change the popup's height based on Commandbar's height.
One thing you may not notice is the height of LayoutRoot(Child of CommandBar) is larger than CommandBar's. By checking the default style of the CommandBar, you can find it uses Grid.Clip and RectangleGeometry.Transform to control the size of the commandbar we can see. You can also check it in the Live Visual Tree in VS. In my case, mycommandbar's Actual height is 48, and LayoutRoot's Actual Height is 60.
So as a workaround, in Compact mode, we can dynamically change the height of "myPopup" by listening the IsOpen property of the commandbar. If IsOpen = true, then substract the LayoutRoot's height(60), if IsOpen = false, substract the height of CommandBar(48).
This works for me.
Try to give your layout some padding ?

Hide Windows Phone 8.1 CommandBar

I am working on a Windows Phone app and I have encountered an "issue". I have a BottomAppBar control on my View and some AppBarButton controls inside the command bar. I would like to "hide" the BottomAppBar in such way that only those three dots on the right side are displayed and the user would have to slide the BottomAppBar control up to see its contents.
I have tried to:
Set the IsOpen property of the CommandBar to False - didn't work
Set all the AppBarButton controls visibility to Collapsed - showed only the empty BottomAppBar
I am not very good at explaining myself, therefore I will add a couple of images from another app on my phone, just to show exactly what I would like to obtain:
you can set the ClosedDisplayMode=Minimal
<Page.BottomAppBar>
<CommandBar ClosedDisplayMode="Minimal">
<CommandBar.SecondaryCommands>
<AppBarButton IsCompact="True" Label="About"/>
</CommandBar.SecondaryCommands>
</CommandBar>
</Page.BottomAppBar>

Show flyout using BottomAppBar

I'm trying to show a simple Flyout (with informational content) when a AppBarToggleButton within BottomAppBar is pressed, but my solution doesn't work. :(
This is my code:
<Page.BottomAppBar>
<CommandBar>
<AppBarToggleButton x:Uid="MapPageAppBarLegend" Label="" Icon="List">
<FlyoutBase.AttachedFlyout>
<Flyout>
<TextBlock Text="Informations here..."/>
</Flyout>
</FlyoutBase.AttachedFlyout>
</AppBarToggleButton>
</CommandBar>
</Page.BottomAppBar>
Nothing appears.. Can anyone help me to showing this flayout?
Thank you very much and sorry for my english language. :)
Pame
Everything is quite clearly described at MSDN (there is also a very good example there):
Nothing appears, because Flyouts open automatically only for buttons (and AppBarToggleButton doesn't derive from Button class):
A flyout attached to a button opens automatically when the user clicks the button. You don't need to handle any events to open the flyout. (This includes controls derived from Button, like AppBarButton
Of course you can add a Flyout to any FrameworkElement but you will have to open it manually:
You can attach a Flyout control to any FrameworkElement object by using the FlyoutBase.AttachedFlyout attached property. If you do so, you must respond to an interaction on the FrameworkElement, such as the Tapped event, and open the Flyout in your code.
In XAML - define your Flyout in Resources and attach it to button:
<Page.Resources>
<Flyout x:Key="myFlyout" Placement="Top">
<TextBlock Text="Informations here..."/>
</Flyout>
</Page.Resources>
<Page.BottomAppBar>
<CommandBar>
<AppBarToggleButton x:Uid="MapPageAppBarLegend" Label="First" Icon="List"
FlyoutBase.AttachedFlyout="{StaticResource myFlyout}"
Click="AppBarToggleButton_Click"/>
</CommandBar>
</Page.BottomAppBar>
And event in code behind:
private void AppBarToggleButton_Click(object sender, RoutedEventArgs e)
{
FlyoutBase.ShowAttachedFlyout((FrameworkElement)sender);
}

Is this concept of a button containing a textbox possible?

Recently I had been looking for a way to make the tabs in a TabControl editable and came across This example on telerik's website. That did exactly what I wanted but it got me thinking about a similar usage for buttons. I was wondering if it would be possible to use something like that and make a button that would show a textbox instead of the content presenter when say, you right click the button? I tried to make something like this work but so far have only ended up with a blank button.
<Button x:Name="SB" Height="222" Width="222" Click="SB_Click">
<ContentControl.ContentTemplate>
<DataTemplate>
<local:SuperButton Content="{Binding Path=x, Mode=TwoWay}"/>
</DataTemplate>
</ContentControl.ContentTemplate>
</Button>
Where x is a string variable and using the code behind from the link above (with a class name change, of course).
edit: This button will be in an itemscontrol, so I don't think naming the inner elements in xaml will work, but I do like the ease of Wolfgang's answer.
The WPF Content Model is really flexible and allows literally anything inside anything.
This is perfectly valid XAML:
<Button>
<TextBox/>
</Button>
Or even:
<Button>
<MediaElement Source="C:\Videos\WildLife.wmv"/>
</Button>
You can simply host a (e.g.) label (TextBlock) with the text AND a TextBox inside the Button and set their Visiblity properties.
That way, if you right click the button, the TextBox shows up.
<Button>
<Grid>
<TextBox Text=normal button caption" x:Name="label" />
<TextBox
x:Name="textbox"
Text="visible on right click"
MouseRightButtonDown="HandleRightClick"/>
</Grid>
</Button>
And then in your C# code create an event handler to set the Visiblity correctly.
void HandleRightClick(object sender, MouseButtonEventArgs e)
{
label.Visibility = Visibility.Collapsed;
textBlock.Visibility = Visibility.Visible;
}

Categories