WPF combobox like popup - c#

I am trying to make a custom popup that will be similar to the combobox one.
I used a Toggle button as the header and a Popup for the content.
<ToggleButton IsChecked="{Binding ElementName=Popup, Path=IsOpen, Mode=TwoWay}">
...
</ToggleButton>
<Popup x:Name="Popup" StaysOpen="False">
...
</Popup>
This works great except one case. When the popup is opened and I click on the ToggleButton again, the popup disappears but then reopens right after.
Looks like when I clicked on the toggle button, Popup detected that the mouse click is outside of the popup so it closes itself and sets ToggleButton.IsChecked = false. Then the click sets IsChecked = true so the popup opens again.
Edit: In such case I would like the popup to close just like the behavior of a Combobox.
Is there a way to solve this problem?

Locate the popup on top of the button so the user can't click on the button. You can do it easily with Placement and so on.

Related

Remove focus from textbox when clicking on parent grid in MVVM

I have a simple window that has a few buttons and a textbox. I want that when I press "Enter" on my keyboard this will trigger a button command but the problem is that when I'm focused on the textbox, I can't press "Enter" because it will just add a linebreak to the textbox.
I tried binding a LeftClick gesture of the grid to a command that uses keyboard.ClearFocus() but I guess that isn't the right function because that didn't work.
Another option which might work but I didn't try yet and I'm not sure if it's even a good practice, is adding x:Name to the textbox, and sending the window as the parameter to the command.
I want that when I click the parent grid of the textbox the focused will be removed from it so I can press "Enter", is there a simple way to do it in MVVM?
You said: "I want that when I press Enter on my keyboard this will trigger a button command"
Have you tried adding InputBindings to the text box?
<TextBox.InputBindings>
<KeyBinding Key="Return" Command="{Binding YourCommand}" CommandParameter="{Binding Path=Text, RelativeSource={RelativeSource AncestorType={x:Type TextBox}}}"/>
</TextBox.InputBindings>

What alternatives do I have to flyout/ContentDialog? (c#, xaml)

I currently have a program where you can load a text in it.
Now I created a button that Pops up a flyout/ContentDialog but Im not happy with it because Limits me of what Im trying to achieve.
When I click the button it opens a flyout, the flyout gets the full Focus. That means I cannot scroll to the text WHILE the flyout-box is open. And if I click outside the flyout-box the flyout-box disappears.
I have a similar Problem to the ContentDialog.
When I click the button and the ContentDialog Pops up, everything behind the ContentDialog goes a bit into White/Grey Color. Also the ContentDialog does not allow any Focus outside the ContentDialog itself.
So what do I want to have?
I want that when I click on the button that a Window appears. I should be able to customize the window (writing text in it and it should have a button).
While this Window is open I want to be able to do Actions outside that window without the window Closing. For example Scrolling through the text I loaded.
Is there something I can achieve this with?
Take a look at the Popup class. This will let you display content on top of other content within your app's window. It's similar to the Flyout but without all of the built-in Flyout behavior that you don't want. The Popup class documentation has more details and commentary on when and how to use it.
Here's a really bland example with no styling.
<Grid>
<Popup x:Name="popup">
<StackPanel>
<TextBlock Text="Poppity pop pop" />
<Button Click="ClosePopup_Click">Close</Button>
</StackPanel>
</Popup>
<Button Click="OpenPopup_Click">Open Popup</Button>
</Grid>
private void OpenPopup_Click(object sender, RoutedEventArgs e)
{
popup.IsOpen = true;
}
private void ClosePopup_Click(object sender, RoutedEventArgs e)
{
popup.IsOpen = false;
}
There is a slightly more complicated example in the Popup documentation
I just hide and show grids with whatever I want inside.

How to set focus to a textbox in a View (User control) selected by a tab view

This is a MVVM WPF Question., c#.
Within a Window I have a Tab control that looks like this
<TabControl TabStripPlacement="Top" >
<TabItem Style="{StaticResource Tabitemstyle}">
<TabItem.Header>
<Label Content="Home" Style="{StaticResource Tablablestyle}"/>
</TabItem.Header>
<v:HomePageView/>
</TabItem>
<TabItem ....
<v:OtherPageView/>
The trick is that there exists a textbox within the 2nd tab item that I wish to have input focus when the user selects the 2nd tab.
I've tried a few solutions, but the closest one so far (using data trigger style, or focused element) almost works:
I can see that the cursor is intended to be within the text box, but it doesn't blink. It seems the focus is still on the tab control in the outside window, not the text box element in the view that is defined by OtherPageView.xaml. When I hit tab once, it is all ok, but this is what I am trying to relieve the users of having to do.
I would use the code behind:
Listen to visibility changed event on the TabItem content (i.e., v:HomePageView)
Find the textbox UI element (you can simply give the textbox a name
in the xaml and refer to it from code behind)
Next, set focus on the text box using the UIElement.Focus() method
Finally if the keyboard did not focus , then use the
Keyboard.Focus(...) method to focus the keyboard on the textbox.

Control doesnt respond to mouse actions because it's on bottom of view hierarchy

I have a ContentControl with following DataTemplate
xmlns:oxy="clr-namespace:OxyPlot.Wpf;assembly=OxyPlot.Wpf"
....
<DataTemplate DataType="{x:Type y:DataGraph}">
<Grid>
<!--Because PlotView is under Label it doesnt respond to mouse actions (click, zoom, etc)-->
<oxy:PlotView Model="{Binding PlotViewModel}"/>
<!--Want Label to be displayed on top-->
<Label Content="some text"/>
</Grid>
</DataTemplate>
I want some text to be displayed on top of oxy:PlotView, but if I do so, oxy:PlotView stops to respond to mouse actions (zoom, click etc).
How can I show label hovering another control, but make bottom control remain responding to mouse actions?
Try setting the IsHitTestVisible property of the Label to False. Mouse clicks will then pass straight through it.
If you're ever wondering where the clicks are going then fire up Snoop, attach to your window, open the Events tab, click on the thing in your program, then see what happened to your event back in Snoop.

TabItem - show popup on hover

I have a TabControl with multiple TabItems, with each TabItem containing multiple sections in the content area. When the user hovers over any Tab, I'd like to show a Popup that shows a list of the sections in that Tab and allow the user to click on the section and navigate to it.
For this question, the portion that I need help with is the closing/opening of the Popups as the user hovers over each Tab. The main sticking points are:
Allowing the user to move the cursor into the Popup area from the Tab. Once the Popup has been opened, it refuses to close on TabItem MouseLeave.
If the user moves from Tab to Tab, the Popup from the previous Tab should close and a new one should open.
The user should only need one click to navigate. This means they shouldn't have to "click away" the popup from one tab in order for another popup to show.
My thought is to expose a DependencyProperty that hit tests which Tab the mouse is over, and trigger the Popup off of that.
Edited for clarity: When moving the mouse over a tab, I show a popup. When I move the mouse away from the Tab, I want the Popup to go close. It has to be a Popup (and not a Tooltip), because the user has to be able to click on the content inside the Popup.
I've sub-classed and re-templated the TabControl, but I would like some help with how to close the Popup on the MouseLeave event. I've triggered on the MouseLeave event, but when the Popup opens, the focus shifts to the Popup so the TabItem MouseLeave event isn't fired properly.
You can use the Interaction.Triggers from the Blend SDK to trigger the popup to close whenever the mouse leaves the popup. Here is a short example:
<Popup Height="300" x:Name="MyPopup">
<Label Content="MyLabel"></Label>
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseLeave">
<ei:ChangePropertyAction TargetObject="{Binding ElementName=MyPopup}" PropertyName="IsOpen" Value="False"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Popup>
You'll need the following namespaces:
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:ei="clr-namespace:Microsoft.Expression.Interactivity.Core;assembly=Microsoft.Expression.Interactions"

Categories