i'm trying to manipulate buttons in my app bar with the proprety enabled and disabled but every time i got an exception telling me System access violation!! any idea about what's going on
<phone:PhoneApplicationPage.ApplicationBar >
<shell:ApplicationBar IsMenuEnabled="True" BackgroundColor="#989898" ForegroundColor="White">
<shell:ApplicationBarIconButton IconUri="/Images/APPBAR/Mes-infos-personnelles copie.png" x:Name="Profile_Button" IsEnabled="True" Text="Profile" />
<shell:ApplicationBar.MenuItems>
<shell:ApplicationBarMenuItem Text="Box" />
</shell:ApplicationBar.MenuItems>
</shell:ApplicationBar>
</phone:PhoneApplicationPage.ApplicationBar>
and in my code behind :
Profile_Button.IsEnabled = false;//exception here
try this
((ApplicationBarIconButton) ApplicationBar.Buttons[0]).IsEnabled = false; // disables Profile_Button button
//disable all buttons and menu item in from app bar
foreach (var button in ApplicationBar.Buttons)
{
((ApplicationBarIconButton) button).IsEnabled = false;
}
//To prevent the menu from opening you have to use this code:
ApplicationBar.IsMenuEnabled = false;
Related
I need some help sorting the visibility of entry on a button click. I have tried a few different things. and the following code is the best result that I have got so far. But its not perfect either.
Requirement: When the page shows in the screen, it would have just a button visible, and when the user clicks on the button, it shows the entry, if they click on the button again, the entry should be set to invisible. If i click outside else where in the page, it should also hide the entry.
XAML.
<controls:CustomButton
Text="Submit"
TextColor="White"
HorizontalOptions="FillAndExpand"
Command="{Binding TextSubmitCommand}"
Icon="WhiteKeyboard"/>
<controls:CustomEntry
x:Name="ItemEntry"
TextColor="White"
HeightRequest="50"
HorizontalTextAlignment="Center"
VerticalOptions="Center"
IsVisible="{Binding EntryVisible, Mode=TwoWay}">
<controls:CustomEntry.Behaviors>
<behaviors:EventToCommand
Command="{Binding LocationSearchCommand}"
EventName="Completed"/>
</controls:CustomEntry.Behaviors>
<controls:CustomEntry.Triggers>
<DataTrigger TargetType="controls:CustomEntry"
Binding="{Binding EntryVisible}"
Value="true">
<Trigger.EnterActions>
<triggers:EntryFocusTrigger/>
</Trigger.EnterActions>
</DataTrigger>
</controls:CustomEntry.Triggers>
</controls:CustomEntry>
View Model
public bool EntryVisible { get; set; } = false;
public Command TextSubmitCommand
{
get
{
return new Command(() =>
{
EntryVisible = !EntryVisible;
});
}
}
Trigger
public class EntryFocusTrigger : TriggerAction<CustomEntry>
{
protected override void Invoke(CustomEntry entry)
{
entry.Focus();
}
}
With the above code, it works perfectly fine toggling the visibility on button click. But if i click else where in the page, the keyboard hides, but the entry will still be there. So i tried adding an event trigger.
Added the following xaml to the custom entry in (XAML Page)
<EventTrigger Event="Unfocused">
<triggers:EntryUnfocusTrigger />
</EventTrigger>
and the actual trigger is defined as:
public class EntryUnfocusTrigger : TriggerAction<CustomEntry>
{
public bool IsVisible { get; set; }
protected override void Invoke(CustomEntry entry)
{
if(entry.IsFocused == false){
entry.IsVisible = false;
}
}
}
But after adding the above code, the entry does not show at all after the first toggle. What would be a clean way to get this working. Look forward for your help.
Try adding this Trigger to hide when the Entry is not Focused:
<Trigger TargetType="controls:CustomEntry"
Property="IsFocused" Value="False">
<Setter Property="IsVisible" Value="false" />
</Trigger>
With this one you don't need a custom Trigger class.
Hope this helps.-
I'm using Prism Library for Xamarin.Forms.
And I'm going to create custom navigation bar via Control template. (Reason of creating custom navigation bar - I didn't find solution to make navigation bar transparent for display background image, also I will probably customize my navigation bar and add some controls on it).
<ControlTemplate x:Key="NavigationPageTemplate">
<AbsoluteLayout BackgroundColor="Transparent">
<Image AbsoluteLayout.LayoutBounds="0,0,1,1"
AbsoluteLayout.LayoutFlags="All"
Aspect="AspectFill"
Source="{TemplateBinding BackgroundImageEx}" />
<ContentView Padding="0,50,0,0"
AbsoluteLayout.LayoutBounds="0,0,1,1"
AbsoluteLayout.LayoutFlags="All">
<ContentPresenter />
</ContentView>
<!--Navigation bar started here -->
<ContentView AbsoluteLayout.LayoutBounds="0,0,1,AutoSize"
AbsoluteLayout.LayoutFlags="PositionProportional, WidthProportional"
BackgroundColor="Transparent">
<ContentView.Padding>
<OnPlatform x:TypeArguments="Thickness"
Android="10"
iOS="10, 20, 10, 0" />
</ContentView.Padding>
<controls:ImageButton Command="{TemplateBinding GoBackCommand}"
HeightRequest="30"
HorizontalOptions="StartAndExpand"
Source="ic_back.png"
WidthRequest="30">
</controls:ImageButton>
</ContentView>
</AbsoluteLayout>
</ControlTemplate>
And my problem is to process back button press with Prism Navigation.
I've tried to process click on MyApp.xaml.cs file.
private void Button_OnClicked(object sender, EventArgs e)
{
NavigationService.GoBackAsync();
}
And it seems to have different navigation stack because it shows after press my first page.
I had Navigation this way:
Navigate("FirstPage"); -> Navigate(MasterDetail/NavigationPage/ViewA) -> Navigate("ViewB")
ViewB - uses Control template.
When I click custom back button on ViewB NavigationService back me to FirstPage. It is incorrect for me. I should back to ViewA!
Another question Should first page be saved when we change App.MainPage?
See the discussion of described problem on https://github.com/PrismLibrary/Prism/issues/1262
To navigate back from ViewA to FirstPage you can intercept the back event and go back again if a variable is passed with a specific value from the ViewB page. Code Example:
Sender:
var navigationParams = new NavigationParameters();
navigationParams.Add("yourVariableName", "YourVariableValue");
_navigationService.GoBackAsync(navigationParams);
Receiver:
public void OnNavigatedTo(NavigationParameters parameters)
{
string myVar = null;
if (parameters.ContainsKey("yourVariableName"))
{
myVar = (string)parameters["yourVariableName"];
}
if(myVar=="YourVariableValue"){
NavigationService.GoBackAsync();
}
}
I don't understand your second question.
I have a pivot control with non data bound pivot items which have different kind of structure. all of them have simple text headers. How can we change the visibility of the headers
based on orientation changes? what I want to achieve is, when the phone is in landscape i want
the headers to be invisible and all the space to be utilized by the the respective contents inside the pivot items. I tried a lot, and the biggest problem is the panel that carries the headers is always taking the original height.(I tried to change font size, visibility etc...)
Please help. Here is my code sample
<controls:Pivot x:Name="pvtMain" >
<controls:PivotItem x:Name="pvtItemOne" Header="My Header one">
<MyUserControls:UserControlOne/>
</controls:PivotItem>
<controls:PivotItem x:Name="pvtItemTwo" Header="My Header Two">
<MyUserControls:UserControlTwo/>
</controls:PivotItem>
<controls:PivotItem x:Name="pvtItemThree" Header="My Header Three">
<MyUserControls:UserControlThree/>
</controls:PivotItem>
</controls:PivotItem>
I am using Windows phone SDK 7.0 (for backwards compatibility reason)
This may work. Give it a try!!
void MainPage_OrientationChanged(object sender, OrientationChangedEventArgs e)
{
if (e.Orientation == PageOrientation.Landscape || e.Orientation == PageOrientation.LandscapeLeft || e.Orientation == PageOrientation.LandscapeRight)
{
pvtItemOne.Header = null;
pvtItemTwo.Header = null;
pvtItemThree.Header = null;
pvtMain.Margin = new Thickness(0, -150, 0, 0);
}
else
{
pvtItemOne.Header = "My Header One";
pvtItemTwo.Header = "My Header Two";
pvtItemThree.Header = "My Header Three";
pvtMain.Margin = new Thickness(0);
}
}
By the way, you don't need to maintain any backward compatibility for 7.0 devices. Microsoft stopped support for those devices long back and Marketplace is closed for those.
You can do the following :
<controls:PivotItem >
<controls:PivotItem.Header>
<Border x:Name="PivotItemHeader">
<TextBlock Text="Test" />
</Border>
</controls:PivotItem.Header>
<StackPanel>
<TextBlock Text="line1" />
<TextBlock Text="line2" />
</StackPanel>
</controls:PivotItem>
By using the "border" inside the Header you can control its visibility from code.
like : PivotItemHeader.Visibility = System.Windows.Visibility.Collapsed ;
I know it is not pretty but it works.
I am attempting to add items to an application bar with behavoirs.
In xaml they look like:
<phone:PhoneApplicationPage.ApplicationBar>
<shell:ApplicationBar IsVisible="True"
IsMenuEnabled="True">
<shell:ApplicationBarIconButton x:Name="Save"
IconUri="/resources/icons/appbar.check.rest.png"
Text="Save" />
<shell:ApplicationBarIconButton x:Name="Cancel"
IconUri="/resources/icons/appbar.cancel.rest.png"
Text="Cancel" />
</shell:ApplicationBar>
</phone:PhoneApplicationPage.ApplicationBar>
<i:Interaction.Behaviors>
<Behaviors:ApplicationBarIconButtonCommand TextKey="Save"
CommandBinding="{Binding SaveEventSetupCommand}" />
<Behaviors:ApplicationBarIconButtonCommand TextKey="Cancel"
CommandBinding="{Binding CancelEventSetupCommand}" />
</i:Interaction.Behaviors>
For multi language support I need to add something like:
Text="{Binding Path=Localizedresources.lblCourse, Source={StaticResource LocalizedStrings}}"
to each button. It would appear that this cannot be done in xaml, hence the use of code.
The button is added in this code:
ApplicationBarIconButton appBarSaveButton = new ApplicationBarIconButton(
new Uri("/resources/icons/appbar.check.rest.png", UriKind.Relative))
{ Text = "Test" };
ApplicationBar.Buttons.Add(appBarSaveButton);
I just can't figure how to add the behavior. This is my start point:
WP7Contrib.View.Controls.Behaviors.ApplicationBarIconButtonCommand
ibc = new WP7Contrib.View.Controls.Behaviors.ApplicationBarIconButtonCommand
{ TextKey = "Test" };
Basically I am looking for a working sample if anyone can oblige.
Thanks
Based on Matt's answer this is my solution:
Add this at the top of the xaml page:
xmlns:Preview="clr-namespace:Phone7.Fx.Preview;assembly=Phone7.Fx.Preview"
and this inside the Grid at the bottom:
<Preview:BindableApplicationBar x:Name="AppBar" BarOpacity="1.0" IsVisible="{Binding IsBarVisible}" >
<Preview:BindableApplicationBarIconButton
Command="{Binding SaveCommand}"
Text="{Binding Path=Localizedresources.lblSave, Source={StaticResource LocalizedStrings}}"
IconUri="/resources/icons/appbar.check.rest.png" />
<Preview:BindableApplicationBarIconButton
Command="{Binding CancelCommand}"
Text="{Binding Path=Localizedresources.lblCancel, Source={StaticResource LocalizedStrings}}"
IconUri="/resources/icons/appbar.cancel.rest.png" />
</Preview:BindableApplicationBar>
References:
http://blog.humann.info/post/2010/08/27/How-to-have-binding-on-the-ApplicationBar.aspx
http://www.codeproject.com/KB/windows-phone-7/CommandToAppBarWP7.aspx?display=Mobile
You cannot specify the Text property of an ApplicationBarIconButton to a resource in XAML, which you've already worked out. To create a behavior and attached it in code you use code similar to the following (modified from an app I'm working on right now):
((ApplicationBarIconButton)this.ApplicationBar.Buttons[0].Text = Strings.NewContact;
var newBehavior = new ApplicationBarButtonNavigation
{
ButtonText = Strings.NewContact,
NavigateTo = new Uri("/views/ContactView.xaml", UriKind.RelativeOrAbsolute),
};
Interaction.GetBehaviors(this).Add(newBehavior);
The principal is the same for your scenario: create the behavior, and then use Interaction.GetBehaviors(this).Add(yourBehavior);
NOTE: In the above examples this refers to the code-behind for the view and is not in the view model.
You can definitely make the ApplicationBar bindable by using the wrapper from http://blog.humann.info/post/2010/08/27/How-to-have-binding-on-the-ApplicationBar.aspx
Not sure about adding commands but this shoudl be possible with the same technique.
The sample code below for a button will trigger opening of a second page.
<Button x:Name="btnSelect" Content="Select" HorizontalAlignment="Right" Margin="0,8,20,6"
Grid.Row="2" Width="200">
<Custom:Interaction.Triggers>
<Custom:EventTrigger EventName="Click">
<GalaSoft_MvvmLight_Command:EventToCommand x:Name="btnSelectClicked"
Command="{Binding SelectEventPageCommand, Mode=OneWay}"/>
</Custom:EventTrigger>
</Custom:Interaction.Triggers>
</Button>
public partial class MainPage : PhoneApplicationPage
{
// Constructor
public MainPage()
{
InitializeComponent();
}
private void ContentGrid_Loaded(object sender, System.Windows.RoutedEventArgs e)
{
Messenger.Default.Register<GoToPageMessage>(this, (action) => ReceiveMessage(action));
}
private object ReceiveMessage(GoToPageMessage action)
{
StringBuilder sb = new StringBuilder("/Views/");
sb.Append(action.PageName);
sb.Append(".xaml");
NavigationService.Navigate(
new System.Uri(sb.ToString(),
System.UriKind.Relative));
return null;
}
}
http://galasoft.ch/mvvm/getstarted/
Can anyone suggest how I can do the same using an ApplicationBarIconButton? I get an error Property 'Triggers' is not attachable to elements of type ApplicationBarIconButton.
Or should I just use CodeBehind?
<phone:PhoneApplicationPage.ApplicationBar>
<shell:ApplicationBar IsVisible="True" IsMenuEnabled="False">
<shell:ApplicationBarIconButton IconUri="/Images/appbar_button1.png" Text="Button 1">
</shell:ApplicationBarIconButton>
</shell:ApplicationBar>
</phone:PhoneApplicationPage.ApplicationBar>
Yeap ApplicationBar is a little bit different fom other controls in Silverlight. I was able to use an ICommand by using this one:
http://blog.humann.info/post/2010/08/27/How-to-have-binding-on-the-ApplicationBar.aspx
or the Silverlight toolkit which offers some extensions as stated in this answer:
How to add an application bar to a user control in wp7 but I never used it.
The ApplicationBar is a service that is provided by the operating system, i.e. not part of the Framework, and doesn't support Triggers as you have already discovered.As mentioned above there are a number of solutions that provide workarounds for this problem.
Alternatively, you could use the ApplicationBarButtonCommand and ApplicationBarButtonNavigation behaviors from the Silverlight Windows Phone Toolkit. It's a simple enough task to create your ApplicationBarMenuCommand if you need one. In your case, for using an ApplicationBar button to navigate to a page, then the ApplicationBarButtonNavigation behavior will do the trick.