Open Window Activate not working with button inside menu - c#

I have a really strange behaviour, and I hope someone can help me out.
I have the following XAML layout:
<StackPanel Orientation="Horizontal">
<Menu>
<Menu.Items>
<MenuItem Padding="2,0,2,0">
<MenuItem.Header>
<Button Content="Details"
Click="Details_Click" />
</MenuItem.Header>
</MenuItem>
</Menu.Items>
</Menu>
<Button Content="Details"
Click="Details_Click" />
</StackPanel>
Please notice that both buttons have the same Event registered.
The Details_Click Event looks like this:
private void Details_Click(object sender, RoutedEventArgs e)
{
var viewer = new DictionaryViewer();
viewer.ShowActivated = true;
viewer.Show();
viewer.Topmost = true;
viewer.Topmost = false;
viewer.Activate();
viewer.Focus();
e.Handled = true;
return;
}
Now I am facing the problem, even with all the code from above the Window doesnt show up activated when I press the button inside the Menu but outside of it works with just .Activate();.
(How I know that window isnt activated: need 2 clicks to close/minimize/maximize it)
Why would my XAML Layout ruin the Activation of the DictionaryViewer(); window, with the button inside Menu?
(To your information the DictionaryViewer is totally empty, its a fresh window nothing implemented yet)
Edit:
Yes, I know there is the MenuItem_Click Event that may make it work, but I need/want the button inside the Menu how can I fix this issue?

THe reason this is happening is because the Button inside the MenuItem is gaining Focus after the Window has opened.
If you set the Focusable property of the button inside MenuItem, this fixes the issue.
E.g.
<StackPanel Orientation="Horizontal">
<Menu>
<Menu.Items>
<MenuItem Padding="2,0,2,0">
<MenuItem.Header>
<Button Content="Details"
Click="Details_Click"
Focusable="False" />
</MenuItem.Header>
</MenuItem>
</Menu.Items>
</Menu>
<Button Content="Details"
Click="Details_Click" />
</StackPanel>

Related

Hide Button but keep function - XAML

First I've tried to implement a Click Event to my Textbox. Unfortunately, it doesn't work with XAML.
So, my plan is to add a Button and whenever you click this Button, the textfield below should change it's letter (back to 1).
My idea was to put the button over the first textbox and to hide it, so that you see the first textbox.
But, if I set the button as hidden, my function doesn't work anymore.
Is there a solution to hide the button, but, still keep the function for the second textbox?
Hidden means control is loaded, takes up space on the screen, but won't be operational(clickable), so it doesn't help you.
You could edit the button's ControlTemplate and make it a simple Grid with Transparent background, without the Hidden part of course.
And last thing, you could add MouseDown function on your TextBox so you won't need the button at all.
If you use bindings and commands you have two ways:
<Button Command="{Binding ClickCommand}">
<Button.Template>
<ControlTemplate TargetType="Button">
<TextBlock Text="Some text"/>
</ControlTemplate>
</Button.Template>
</Button>
or
<TextBlock Text="Some text">
<TextBlock.InputBindings>
<MouseBinding Gesture="LeftClick" Command="{Binding ClickCommand}"/>
</TextBlock.InputBindings>
</TextBlock>
Got it!
.xaml:
<TextBox MinWidth="90" x:Name="txtBoden" TextChanged="TxtBoden_TextChanged"
PreviewMouseDown="txtBoden_MouseDown"></TextBox>
.cs:
public void txtBoden_MouseDown(object sender, MouseButtonEventArgs e)
{
txtFach.Text = "1";
}

Blend UWP flyout tool not staying open

I am currently making a UWP in Blend in Visual Studio 2017 but I am having trouble with the flyout tool. I was hoping to manually control when it opens and when it closes essentially disabling the feature when it closes by itself when it loses focus so that I may be able to interact with other tools or objects in the app before closing the flyout. I have tried adding some C# codes to attempt this but I have had no success. I'm not sure either if this would need to be altered in the template or if it can be done from XAML or preferably C#. I have attached the flyout to a stackpanel and added a button click event in a separate location with the following code:
flyout.AllowFocusOnInteraction = true;
flyout.AllowFocusWhenDisabled = true;
flyout.ShowAt(stackpanel);
I was hoping this would work to keep the flyout open but it doesn't. I have another button that I had in mind to close it with the following C# code:
flyout.Hide();
But it would seem that it is not necessary because it closes automatically still regardless of the code. Does anyone have any suggestions?
Represents a control that displays lightweight UI that is either information, or requires user interaction. Unlike a dialog, a Flyout can be light dismissed by clicking or tapping outside of it, pressing the device’s back button, or pressing the ‘Esc’ key.
For your scenario, the Flyout control is not reasonable choice. You could achieve this by using ContentDialog. And the following code realizes the feature of contentDialog.
<ContentDialog
x:Class="AppUIBasics.ControlPages.ContentDialogExample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:AppUIBasics.ControlPages"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Title="SIGN IN"
PrimaryButtonText="sign in"
SecondaryButtonText="cancel"
PrimaryButtonClick="ContentDialog_PrimaryButtonClick"
SecondaryButtonClick="ContentDialog_SecondaryButtonClick">
<StackPanel VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
<TextBox Name="userNameTextBox" Header="User name"/>
<PasswordBox Name="passwordTextBox" Header="Password" IsPasswordRevealButtonEnabled="True"/>
<CheckBox Name="saveUserNameCheckBox" Content="Save user name"/>
<TextBlock x:Name="errorTextBlock" />
<TextBlock Text="Lorem ipsum dolor sit amet, consectetur adipisicing elit." TextWrapping="Wrap" />
</StackPanel>
</ContentDialog>
This the official code sample about UWP UI basic that you can refer to. If you insist on using Flyout contorl. You could refer to my code sample. However it is not suggested by the official.
MainPage.xaml
<Button Content="Show Flyout">
<Button.Flyout>
<Flyout x:Name="flyout" Closing="flyout_Closing" >
<StackPanel>
<TextBox x:Name="MyTextBox" Text="You can edit this text by tapping it."/>
<Button Content="close" Click="Button_Click"/>
</StackPanel>
</Flyout>
</Button.Flyout>
</Button>
MainPage.xaml.cs
private bool manual = false;
private void flyout_Closing(FlyoutBase sender, FlyoutBaseClosingEventArgs args)
{
if(manual == true)
{
args.Cancel = false;
}
else
{
args.Cancel = true;
}
manual = false;
}
private void Button_Click(object sender, RoutedEventArgs e)
{
manual = true;
flyout.Hide();
}

StackOverflowException when trying to show a ContextMenu and clicking on its parent

I've encountered a weird behavior in WPF. Even though there are quite a few ways to avoid this problem, I'm trying to better understand why it's happening:
I created a new WPF application, just added a button which has a ContextMenu:
<Grid>
<Button x:Name="btnTest" Margin="10,10,10,10"
MouseEnter="BtnTest_OnMouseEnter" MouseLeave="BtnTest_OnMouseLeave">
<Button.ContextMenu>
<ContextMenu x:Name="myContext">
<TextBlock Text="Context Menu Text"></TextBlock>
</ContextMenu>
</Button.ContextMenu>
</Button>
</Grid>
In the code behind I use MouseEnter to show the ContextMenu and MouseLeave to hide it:
private void BtnTest_OnMouseEnter(object sender, MouseEventArgs e)
{
myContext.PlacementTarget = btnTest;
myContext.Placement = PlacementMode.Bottom;
myContext.IsOpen = true;
}
private void BtnTest_OnMouseLeave(object sender, MouseEventArgs e)
{
myContext.IsOpen = false;
}
So now - I see the ContextMenu under the button when the mouse is on the button and it hides when the mouse leaves the button.
BUT when I click the button I get an exception
An unhandled exception of type 'System.StackOverflowException'
occurred in WindowsBase.dll
Question is - Why is the Mouse Click, specifically, triggering this exception? I don't have any code of mine running on the Click event, yet without clicking an exception doesn't occur...
BTW: Same will happen if I replace the Button with an Image for instance, so it doesn't seem to be caused by a specific control...
Change your XAML like this:
<Grid>
<Popup x:Name="myContext">
<TextBlock Text="Context Menu Text"></TextBlock>
</Popup>
<Button x:Name="btnTest" Margin="10,10,10,10"
MouseEnter="BtnTest_OnMouseEnter" MouseLeave="BtnTest_OnMouseLeave">
</Button>
</Grid>
I think there is a loop of this sort going on in your code:
you enter the button, the popup shows
you click, popup hides (default behavior of contextmenu)
button gets focus, popup is shown again
What happens if you set the ´StaysOpen´ property of the ContextMenu? If you then dont get this behavior anymore my suspicion is correct.

Disable button when clicked and make other buttons enabled

i have three buttons in my wpf window what is the best way to disable button when clicked and make other two button enabled
<Button Name="initialzeButton"
Width="50"
Height="25"
Margin="460,0,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Click="initialzeButton_Click"
Content="Start"
Cursor="Hand" />
<Button Name="uninitialzeButton"
Width="50"
Height="25"
Margin="0,0,64,0"
HorizontalAlignment="Right"
VerticalAlignment="Center"
Click="uninitialzeButton_Click"
Content="Stop"
Cursor="Hand" />
<Button Name="loadButton"
Width="50"
Height="25"
Margin="0,0,9,0"
HorizontalAlignment="Right"
VerticalAlignment="Center"
Click="loadButton_Click"
Content="Load"
Cursor="Hand" />
now i use this way in each button :(
private void uninitialzeButton_Click(object sender, RoutedEventArgs e)
{
this.uninitialzeButton.IsEnabled = false;
if (!this.initialzeButton.IsEnabled)
{
this.initialzeButton.IsEnabled = true;
}
if (!this.loadButton.IsEnabled)
{
this.loadButton.IsEnabled = true;
}
}
What is your definition of 'best way'? Is it quick and few lines of code or elegant or..
Several ways come into my mind:
- Use MVVM Light: 1 relaycommand for the three buttons, 3 dependency objects (properties in the viewmodel) for isEnabled which will all be set to false, only set isEnabled to true for the button clicked (which could be sent as a parameter in the relaycommand).
- Use booleanconverters/booleaninverterconverters on the isEnabled property.
- Restyle radiobutton to look like a button, replace the three buttons with a radiobutton group. When one radiobutton is selected, the other ones will be deselected, style them as disabled. Prevent deselected items from being clicked.
Regards,
Michel
you can do somthing like this on page load -
PostBackOptions postBackOptions = new PostBackOptions(Button1);
Button1.OnClientClick = "this.disabled=true;";
Button1.OnClientClick += ClientScript.GetPostBackEventReference(postBackOptions);
For a pure XAML solution wrap them in a style stripped ListBox and tie the click to selection, and selection to disabled state.

WPF: Show Panel on Right-click

I'm trying to have a WPF ViewBox 'appearing' at the cursor position in a user control when the user right-clicks on the control. Right now, I have the code:
<!-- XAML -->
<Viewbox Width="100" Visibility="Collapsed" x:Name="actionBox">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Stretch">
<Button>Item ▼</Button>
<Button>Permute ▼</Button>
<Button>Generate ▼</Button>
</StackPanel>
</Viewbox>
and
/* C# */
private void setPanel_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
{
Point p = e.GetPosition(this);
actionBox.Margin = new Thickness(p.X, p.Y, 0, 0);
actionBox.Visibility = System.Windows.Visibility.Visible;
actionBox.BringIntoView();
}
The event does get fired, but nothing seems to happen. (The MouseRightButtonDown="..." is in a different part of the XAML file.)
How would one go about writing this in WPF?
Have a look at the Context Menu.
<ContextMenu Name="cm" StaysOpen="true">
<MenuItem Header="Item ▼"/>
<MenuItem Header="Permute ▼"/>
<MenuItem Header="Generate ▼"/>
</ContextMenu>
You can even bind the commands with the menu items as well create submenus.
Fore more information:
http://www.a2zdotnet.com/View.aspx?id=92

Categories