I am using C# and XAML and Template10. I have an AutoSuggestBox in a command bar. It is all working fine but the dropdown list does not close when I make my selection. The selection activates new content that is covered up by the stuck dropdown. It only closes if I click on the icon on the textbox, not the listed item that was selected. How is this dropdown closed programmatically in C# or XAML?
<AutoSuggestBox x:Name="asb2"
RelativePanel.AlignRightWithPanel="True"
PlaceholderText="Search for..."
TextChanged="asb_TextChanged"
QueryIcon="Find"
QuerySubmitted="asb_QuerySubmitted"
SuggestionChosen="asb_SuggestionChosen"
Margin="10,0"
Height="40"
MinWidth="250"
BorderThickness="1" />
Code behind:
private void asb_SuggestionChosen(AutoSuggestBox sender, AutoSuggestBoxSuggestionChosenEventArgs args)
{
asb2.IsSuggestionListOpen = false;
var contact = args.SelectedItem as AutoContact;
sender.Text = string.Format("{0} *** ({1})", contact.Word, contact.Nick);
AddressBox.Text = contact.Url;
GoButton_Click();
}
Solved! I was clearing the last AutoSuggestBox text before reading the text. This kept the drop down box open because no suggestion was there to make it disappear. Moved clearing the AutoSuggestBox to OnFocus. This allowed the text to end the dropdown. When I click the AutoSuggestBox again starts empty.
Related
I am building a small UWP app in C#, to scan EAN barcodes and assigning descriptions to it.
The default action when I click on my textboxes is to start speech recognition. And I want the textbox to go into manual editing mode, when I rightclick it (long tap on touch-devices).
Therefore I'd like to remove the default context-menu for my TextBox control.
I know how to do this in Windows Forms applications (just add an empty TextBox.ContextMenu with visibility=Collapsed).
Can somebody here help me please, and tell me how to remove the default "Paste" context menu (or "flyout") entry from my textboxes?
Is this even possible?
Screenshot: UWP default Textbox context menu
You can to disable context menu of TextBox, ContextMenuOpening event will help you. Below is the whole code.
XAML:
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<TextBox x:Name="textBox" Text="test" Height="80" Width="100" ContextMenuOpening="TextBox_ContextMenuOpening" />
</Grid>
C#:
private void TextBox_ContextMenuOpening(object sender, ContextMenuEventArgs e)
{
e.Handled = true;
}
I have the following textbox in a user control.
<!-- This is the user input TextBox, users type commands here and hit enter or press the send command button -->
<TextBox Text="{Binding CommandText}" Background="Transparent" BorderBrush="{StaticResource brushWatermarkBorder}" Name="txtUserEntry">
<TextBox.InputBindings>
<KeyBinding Command="{Binding BindKeyCommand}"
CommandParameter="{Binding ElementName=txtUserEntry, Path=Text}"
Key="Return"
Modifiers=""/>
</TextBox.InputBindings>
</TextBox>
and button.
<!-- This button serves as an alternative to hitting the enter key with text box focus. -->
<Button Command="{Binding BindKeyCommand}" CommandParameter="{Binding ElementName=txtUserEntry, Path=Text}" Grid.Column="2">
<TextBlock>
Send Command
</TextBlock>
</Button>
When a user types into the box and uses the return key too send the command, the command is sent through the BindKeyCommand successfully (a messagebox pops up to confirm this) and focus is maintained on the text box.
However, when a command is sent using the Button, the command is, once again, successful, but the focus on the text box is lost.
I have attempted to implement the answers here but all to no avail. Could someone please explain to me, either, how to correctly implement the answers here, including what to put in the view model, or, an alternative method such that, on button press, the keyboard focus is assigned back to the textbox. It might be important to note, just as in the linked question, I am using MVVM.
UPDATE: Trying to carry out steps by DT Sawant
Step 1:
ApplicationName.Tools.FocusExtension contains all of the text within second highest rated answer. Extension is in namespace ApplicationName.Tools
Step 2:
Added new property;
private bool isTxtUserEntryFocused = false;
public bool IsTxtUserEntryFocused
{
get
{
return isTxtUserEntryFocused;
}
set
{
isTxtUserEntryFocused = value;
OnPropertyChanged("IsTxtUserEntryFocused");
}
}
Step 3:
Added namespace reference; xmlns:Tools ="clr-namespace:WPFLocalDataConnect.Tools"
Step 4:
Bound IsFocused property; Tools:FocusExtension.IsFocused="{Binding IsTxtUserEntryFocused}"
Step 5:
Initializing in viewmodel thusly;
public void ExecuteBindKeyCommand(string param)
{
if (String.IsNullOrWhiteSpace(param))
{
MessageBox.Show("No command given.");
this.CommandText = string.Format("");
IsTxtUserEntryFocused = true;
}
else
{
MessageBox.Show(string.Format("CommandInvoked: {0}", param));
History = string.Format("{0} {2} {1}", History, param, Environment.NewLine);
this.CommandText = string.Format("");
IsTxtUserEntryFocused = true;
}
}
Now all steps are completed I tested the project. It did not work but some interesting things to note;
Pressing the button WITHOUT first focusing the textbox results in "no command" message followed by focus move to textbox. Pressing the button after clicking in the textbox, either entering or not entering text results in "no command" or "command invoked" messages respectively followed by no focus move to the textbox. THIS IS SO CONFUSING.
You can do something like this in code behind to set the focus
<Button Click="MyButton_Click" Name="MyButton" Command="{Binding BindKeyCommand}" CommandParameter="{Binding ElementName=txtUserEntry, Path=Text}" Grid.Column="2" >
<TextBlock>
Send Command
</TextBlock>
private void MyButton_Click(object sender, RoutedEventArgs e)
{
Dispatcher.BeginInvoke(DispatcherPriority.ContextIdle, new Action(() => txtUserEntry.Focus()));
}
As you have attempted to solve your issue with the help of
this link. I will explain the steps to implement the same solution:
step 1: Add new class FocusExtension as given in above link.
step 2: Add new property IsTxtUserEntryFocused(you can give any name) in your viewmodel
step 3: Add namespace reference of FocusExtension Class in your XAML
step 4: Bind IsFocused property of FocusExtension class to your viewmodel property.
As shown in below:
<TextBox local:FocusExtension.IsFocused="{Binding IsTxtUserEntryFocused}" />
step 5: Now in your button command which you might have implemented in your view model.
Initialize
IsTxtUserEntryFocused=true.
The focus is not retaining on Textbox because your displaying message box.
So focus goes to message box and it does not come back to your window.
You should add this line after your displaying messagebox
Application.Current.MainWindow.Focus();//Bring focus to your window where text box is present
That's it.
In my app,there is a need to do this
At start,the checkbox is unchecked
user tap,and then pop up a messagebox as a alarm to make sure user indeed want to do it(At the moment the checkmark is still collapse)
If user click "Yes,I want to do it",then checkmark is visible and now it is checked
vice versa
I found that,when I tap the checkbox,Checked event is always triggering
and
the checkmark is always turn to "checked" state
How to solve the problem???
Any advice would be great,Thanks!!!
Just a trick is needed. Sharing a sample with you.
overlap a transparent background grid over your checkbox with a transparent background like this.
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<StackPanel>
<Grid>
<CheckBox Name="cb" Content="cb" Checked="CheckBox_Checked_1"/>
<!--Grid that overlaps the checkbox-->
<Grid Background="Transparent" Tap="Grid_Tap_1"/>
</Grid>
</StackPanel>
</Grid>
This overlapping wont call any checkbox event even if you tap on it
now in code of the event
private void Grid_Tap_1(object sender, GestureEventArgs e)
{
if(MessageBox.Show("Message")==MessageBoxResult.Ok)
{
cb.IsChecked=True;
}
}
Instead of Tap Event, Try Checked and Unchecked Events of the checkbox.
Note: You can track the checked status in "Checked" and "UnChecked" events of the Check Box using IsChecked Property and write your code in appropriate events.
After Asking confirmation to user.
If the user clicks "Yes" , set chkBox.IsChecked=true;
else
If the user clicks "No", set chkBox.IsChecked=false;
I think there is no way to stop checkbox default behaviors. So you can create a custom control with a image and a textbolck inside a stack panel. You should use pair of images for "Image" Control Source one for unchecked and another for checked.
//At start,the checkbox is unchecked
<StackPanel x:Name="panelCheckBox" Tap="panelCheckBox_Tap_1" Orientation="Horizontal">
<Image Source="UncheckImageSourc" x:Name="ImgeCheckBox"/>
<TextBlock Text="CheckBox Content"/>
</StackPanel>
In Code Behind
bool IsChecked=false;
private void panelCheckBox_Tap_1(object sender, System.Windows.Input.GestureEventArgs e)
{
//If user click "Yes,I want to do it",then checkmark is visible and now it is checked
if(!IsChecked)
{
IsChecked =true;
ImgeCheckBox.Source = "CheckImageSource";
}
else
{
IsChecked =false;
ImgeCheckBox.Source = "UncheckImageSourc";
}
}
I have a user control that contains a scroll viewer. inside the scroll viewer I placed another user control with grid, and inside the grid there is a combo box.
all this is placed inside a RadWindow.
Something like this:
first user control: (displayed inside a RadWindow)
<UserControl x:class = "MyFirstUserControl">
<Grid>
<ScrollViewer>
<StackPanel x:Name="stackPanel"/>
</ScrollViewer>
</Grid>
</UserControl>
second user control:
<UserControl x:class = "MySecondUserControl">
<Grid>
<telerik:RadComboBox x:Name = "comboBox"/>
</Grid>
</UserControl>
in code behind I add the second user control to the stackPanel:
stackPanel.Children.Add(new MySecondUserControl());
Now, the problem is: when the combo-box drop down is open, and I scroll up / down the control - I expect it to close, but- it remains open...
I try to catch the MouseLeftButtonUp event of the scroll bar, and set the IsDropDownOpen of the comboBox to false, but it is false nonetheless and the drop-down still open.
How can I force the drop-down to close when focus is not on it, even if the focus is out of the combo control altogether?
Thanks,
I've been pounding away at this issue for a little while, and have only found part of the solution.
I'm trying to set up a TabControl so that I can in some cases prevent the user from changing the currently selected tab. When the user is prevented from changing the currently selected tab, then they are shown a dialog box.
I have already read the following documents:
WPF - reset ListBox scroll position when ItemsSource changes
http://wizardsofsmart.net/uncategorized/itemssourcechanged-event-using-attached-dependency-properties/
http://joshsmithonwpf.wordpress.com/2009/09/04/how-to-prevent-a-tabitem-from-being-selected/
http://social.expression.microsoft.com/Forums/en-US/wpf/thread/f7b46018-1e97-4bbe-ada8-49b75dbc1da2/
I have implemented the solution indicated in the 3rd link (though all of the above create the same error seen below). And it works, but...
Things mess up thoroughly if the user does the following:
attempts to change the tab when such an action is disallowed. The MessageBox pops up with the error.
the user clicks "OK" and is returned to the original window.
the user tries again to change the tab. No MessageBox appears.
if the user minimizes the window, and then maximizes it again, then the MessageBox that was supposed to appear earlier appears.
the user clicks "OK" and is returned to the original window... but the tab has been changed to the one they selected before, even though they should not be able to change tabs.
This is obviously not ideal behavior. Why isn't the MessageBox appearing the second time, and why is the tab changing when it should be disallowed from doing so?
If I remove the MessageBox part, it works fine.
Here is the code for the TabControl.SelectionChanged event handler:
bool _isChanging = false;
private void tabControlForNavigation_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (!_isChanging && canChangeTabs.IsChecked.HasValue)
{
_isChanging = true;
bool canLeave = canChangeTabs.IsChecked.Value; //normally this would be replaced by a check in the ViewModel
if (!canLeave)
{
int prevIndex = tabControlForNavigation.Items.IndexOf(tabControlForNavigation.SelectedContent);
tabControlForNavigation.SelectedIndex = prevIndex;
MessageBox.Show("Can't change tabs!"); //if I comment out this line, everything works fine.
}
_isChanging = false;
}
}
I am using MVVM to implement this. The Window looks like this:
<Window x:Class="TestTabControlSwitching.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow"
Height="350"
Width="525">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition />
</Grid.RowDefinitions>
<CheckBox x:Name="canChangeTabs"
Content="Can Change Tabs"
IsChecked="True" />
<TabControl x:Name="tabControlForNavigation"
Grid.Row="1"
IsSynchronizedWithCurrentItem="True"
ItemsSource="{Binding Collection}"
SelectedItem="{Binding SelectedItem}"
SelectionChanged="tabControlForNavigation_SelectionChanged"
Margin="4"
HorizontalAlignment="Stretch">
<TabControl.ItemTemplate>
<DataTemplate>
<ContentPresenter Content="{Binding Path=Name}" />
</DataTemplate>
</TabControl.ItemTemplate>
</TabControl>
</Grid>
I'm omitting the rest of the code for sake of brevity- there is a pretty straight-forward ViewModel structure backing the window.
As you noticed, the problem is the MessageBox inside the event handler. The focus will change to the MessageBox and you can get all kind of undesired effects. I've had my own problems with this.
Here is a couple of SO question on the same subject
WPF: Does MessageBox Break PreviewMouseDown?
Wpf stop routing event when MessageBox appear?
If you must display a message to the user then an alternate approach might be to create a new Window which you style like a MessageBox and then call Show (not ShowDialog) on it inside the event handler.
I know this post is a bit old, but I have a very easy way to accomplish this:
Use the tab_Enter event and create a method that performs your check and displays a MessageBox to the user and then set myTabs.SelectedIndex to the prior index. A simple example:
private void someTab_Enter(object sender, EventArgs e)
{
if (myCondition)
{
MessageBox.Show("Sorry, myCondition will not let you move to this tab.");
myTabs.SelectedIndex = someOtherTabIndex;
}
}
This was a very detailed question. I had the same problem you had (i.e. the message box doesn't display on 2nd or 3rd selection changed until you minimize and maximize the window) and after much debugging and multiple google searches, stumbled on the below linked MSDN forum post.
[TabControl SelectionChanged Strange Behaviour?]
Please ignore the poorly formatted question and answer. But as mentioned in the answer, putting it inside a dispatcher and focussing the selected tab after setting the index resolved the issue for me.
You are missing an easy trick. Just make focusable=False for the Tab header.
<TabItem Header="MY TAB" Focusable="False">
You could bind this property to your view model.
<TabItem Header="MY TAB" Focusable="{Binding Bool_CanHasCheeseBurger}">