Custom context menu XAML for WP8 - xaml

I try to implement a custom ContextMenu in a LongListSelector.
I'm not using the ContextMenu from Microsoft.Phone.Controls.Toolkit, it's basically the same as in the Rowi App:
(source: hiddenpineapple.com)
Approach 1
My list item toggles a VisualState on hold and an overlay is shown with controls in it.
The problem
I can't find a way to go back to the default state when the user clicks outside of the list item (as in the default ContextMenu).
Approach 2
I've implemented a custom template for the toolkit ContextMenu which looks exactly the same. I had to move its margin top to -itemHeight, as by default it is below the item.
The problem
The problem with this solution is, that it automatically closes itself when opening and I couldn't figure out how to avoid this.
Another problem was that it didn't work well with TiltEffect.IsTiltEnabled from the Toolkit (visual problems).
I need your help
Any suggestions on how to get this working?
Answer
Thanks to Cheese, now I know how to properly close the menu when the user clicks outside.
His suggestion was to get the coordinates of a Tap event on the current page, and check if it's inside the menu. When not, close the menu.
So I added a Tap listener to the page when the menu opens, and removed it when the menu closes. From the page listener I got the event coordinates and could check if it's inside the control which holds the menu (same size and position). I received the position of the control with Point leftUpperPoint = control.TransformToVisual(page).Transform(new Point(0, 0)) and the rightLowerPoint by adding the ActualWidth and ActualHeight.
But then I realized:
Why should I even calculate if the tap is inside the menu? I always want to close the menu when the user taps anywhere on the screen. If it's outside, yes. If it's on a menu button, yes.
Another modification I made was to listen for MouseLeftButtonDown instead of Tap as it also triggers when the user swipes.
So I removed this code and came up with the following:
private void ToggleMenu(object sender, System.Windows.Input.GestureEventArgs e)
{
PhoneApplicationFrame frame = ((PhoneApplicationFrame)Application.Current.RootVisual);
VisualState state = this.States.CurrentState;
if (state == null || state.Name == "DefaultState")
{
frame.MouseLeftButtonDown += MouseDownDelegate;
this.State = "MenuState";
}
else
{
frame.MouseLeftButtonDown -= MouseDownDelegate;
this.State = "DefaultState";
}
}
private void MouseDownDelegate(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
ToggleMenu(sender, null);
}
This works perfectly!
Thanks to Cheese for the hint.

Something like this by #denniscode http://dotnet.dzone.com/articles/rowi-show-tap-menu

Approach 1 problem
The best solution would be:
Get the menus coordinates, when user makes a tap - you check are tap coordinates on menu or not, if not - dissmiss - simple.
Approach 2 problem
I guess you had some button in a corner and when you tapped on it - nothing happened? And when you dissmissed the Tilt all worked. It seems that tilt works faster than a click, so, tilt changes the button coordinates, and device thiks you have missed/or dragged off

You can use what #ScottIsAFool suggested and maybe create another Dependency Property on your TapMenu control of type UIElement named CloseWhenTappedElement and automatically listen for Tap events inside your control once set. For example
<Grid x:Name="TapArea"/>
<TapMenu CloseWhenTappedElement="{Binding ElementName=TapArea"}/>

Related

How to hide and show group of controls using Panel [duplicate]

I am designing a multipage windows form using panels.
I'm displaying a login form and validating the button click, and want to hide the login panel and show the main panel.
However, when I click the button, the login panel disappears alright, but the main panel does not appear. since there is nothing to display, the form window shrinks to just the minimize/maximize/close buttons.
Here's the code for the button:
private void btn_login_Click(object sender, EventArgs e)
{
if (pwdBox.Text == optopwd)
{
MessageBox.Show("Good Morning!!");
loginpanel.Visible = false;
mainpanel.Visible = true;
}
else MessageBox.Show("Incorrect password!");
pwdBox.Text = "";
}
Please let me know what I have missed/misunderstood. Thanks!
Edit:
Screenshots:
Login Screen:
http://img641.imageshack.us/img641/9310/loginscreenj.jpg
Empty window:
http://img163.imageshack.us/img163/1376/emptyx.jpg
The standard mistake is that you accidentally put the mainpanel inside the loginpanel. So when you make loginpanel invisible, the mainpanel can never become visible. This accident is common in the designer, it won't let you put two panels on top of each other. You fix it with View + (Other Windows) + Document Outline. Drag mainpanel and drop it on the form. You'll have to fix the Location property by editing it in the Properties window instead of moving the panel with the mouse.
An entirely different approach is to use a TabControl. Easy in the designer, you just need to hide the tabs at runtime. Code is here.
Or use two UserControls.
Looks like your for is automatically resizing. There are 2 properties on the form responsible for auto size:
AutoSize = True;
AutoSizeMode = GrowAndShrink;
If you have the above settings then your form would shrink just to control panel (buttons) if there's nothing else to display.
Let me know if that helps.
UPDATED
also... does your control "pwdBox" belong to main panel?
Two suggestions:
Try setting the height attribute to 100%
mainpanel.Height = 100%
If that doesn't work, ensure that the page isn't initializing with mainpanel.visible set to false on a postback.

How to make a default button in UWP app using XAML?

I'm trying to declare a button as default in UWP app but receive an error:
The property 'IsDefault' was not found in type 'Button'
How can I make a default button in UWP app?
I down know what IsDefault is in WPF but to get if a button is pressed in UWP you can use CoreWindow.GetForCurrentThread().KeyDown. Create a Method that will be called from when the button is pressed or VirtualKey.Enter is clicked.
public MainPage()
{
this.InitializeComponent();
CoreWindow.GetForCurrentThread().KeyDown += MainPage_KeyDown; ;
}
private void MainPage_KeyDown(CoreWindow sender, KeyEventArgs args)
{
switch (args.VirtualKey)
{
case Windows.System.VirtualKey.Enter:
// handler for enter key
break;
default:
break;
}
}
You can use key down event which you can place on any textbox for example if you are making a login page then probably there will be 2 textboxes for username and password then just add key down event handler to textbox as it will be the last mandatory field like this:
<PasswordBox KeyDown="PasswordKeyDown"/>
then you can handle this event as:
using System.Windows.Input;
private void PasswordKeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Enter)
Login();
}
Hope it will help you :)
There is not easy or clean way to solve your problem because IsDefault is not available for uwp apps.
if you are using MVVM or you want to reuse your code I recommend you to use Behaviors and follow the examples that the other guys posted.
I need a Button which user can invoke by pressing the ENTER key.
In an UWP app, by default a Button can be invoked by pressing the Enter key. So I guess what you want is setting the focus on this Button when there are some other UIElements in your page.
You can refer to Keyboard navigation among UI elements,
By default, the tab order of controls is the same as the order in which they are added to a design surface, listed in XAML, or programmatically added to a container.
To focus on the Button which is not the first element, you can just give the TabIndex="1" property to your Button, this property can make your Button get focus whenever the page is loaded, but if you change the focus on other controls in this page, you will need to reselect this button by mouse clicking, touching or TAB key.

Windows 8 appbar on selected item (like startup screen)

What I want to achieve in my application is the same as what windows did on their start up screen. When you select an item, open the appbar and show more items. When you just open te appbar when not selecting anything, don't show those items.
So far so good and it works like I want it to be. But there is some issue I can't solve. When you select an item on the start up screen, you can't close te appbar when right clicking anywhere on the screen. You have to deselect the item.
I just can't figure out how to disable that right click to close the appbar. Because then I am in a state where I have a selected item, but no appbar. I don't want that...
Thanks in advance!
There is a property called IsSticky
this can be used to stop you appbar from collapsing.
the other option you have is to hooking into Closed event and force it to re-open.
Based on the screen you provided aka the Metro UI :) i'd say that create a page that just hosts other tiles.
I have done a similar thing in one of my apps, have a look at
http://apps.microsoft.com/windows/en-gb/app/cineworld/7adfde16-33c3-4b51-b758-00366325288d
Have a look at Coding4Fun or Callisto
Set the AppBar property IsSticky="true" and handle the event RightTapped on your GridView/ListView, and in the event handler set e.Handled = true;
This will stop the rightclick/swipe routed event from reaching Page and it won't close the AppBar.
You could override the hide() function of the appbar and replace it with something like this:
appBar.hide = function () {
/// <signature helpKeyword="WinJS.UI.AppBar.hide">
/// <summary locid="WinJS.UI.AppBar.hide">
/// Hides the AppBar, if visible, regardless of other state
/// </summary>
/// </signature>
// Just wrap the private one
var listView = document.getElementById("yourListView").winControl;
var count = listView.selection.count();
if(count <1)
this._hide();
}
It's not a great workaround, but it works like a charm :)

Loading UserControl within a Child Window

I have a child window created in silverlight. I need to load a user control within the child window(for a content change in the same child window) on a button click.
How can i acheive this?
Say for Example: If i have a child window with a Header -> Content -> Button.
I just need to change the content part and the button part on click of the button.
I need to change the buttons also since navigation is not possible using the same button click events.
Is it possible to acheive this in Silverlight 4.0 or 5.0?
Here is one way to do it. Create a canvas to hold the content and on button click, add the user control and add it as a child to the canvas. If you want to change the button, rather than changing the button, in the same button click the button content to a different text.
private void Button_Click_1(object sender, RoutedEventArgs e)
{
SilverlightControl1 control1 = new SilverlightControl1();
top.Children.Add(control1);
}
Hope this helps.

adding images to the label suggestion

In my project I need to create some play,pause,stop buttons in one composite.
For that I created one composite and added these buttons there. Also I have added the images
for each button. But after drawing, it does not look good. I mean images on the buttons does not look good.Clients are not satisfied. Now is it possible to add Images to Label and give some Toggle button actions to the label? I know I can add images to the label. But when I click the label,it does not give button effect..
If you want a custom look for your 'buttons' you could use labels with custom images (one for the normal state and one for the "pushed" state. Something like:
final Label stop = new Label(composite, SWT.NONE);
stop.setSize(STOP_IMG.getImageData().width, STOP_IMG.getImageData().height)
stop.setBackgroundImage(STOP_IMG);
stop.addMouseListener(new MouseAdapter()
{
#Override
public void mouseUp(MouseEvent e)
{
stop.setBackgroundImage(STOP_IMG);
}
#Override
public void mouseDown(MouseEvent e)
{
stop.setBackgroundImage(STOP_DOWN_IMG);
// DO ACTION
}
});
For a nice UI you could also add a MouseTrack listener and have different images for the mouse over states.
Disadvantage of this is you are making it less accessible as it will only respond to mouse events. If you go for this approach you should look at creating your own class that extends MouseAdapter, and takes the label, images and action to invoke in a constructor so you don't end up with tonnes of very similar anonymous classes.
I have used toolbars in the past to achieve a nice effect.
This will create a toolbar with an item that behaves like a regular button:
//Toolbar button
ToolBar toolBar = new ToolBar(composite,SWT.FLAT);
ToolItem toolItem = new ToolItem(toolBar,SWT.PUSH);
toolItem.setImage(image);
This will a toolbar with an item that has toggle behaviour:
//Create a toggle effect
ToolBar toggleToolBar = new ToolBar(composite,SWT.FLAT);
ToolItem toggleToolItem = new ToolItem(toggleToolBar,SWT.CHECK);
toggleToolItem.setImage(image);