How to avoid multiline TextBox Enter keypress is swallowed when using InputBindings? - c#

I'm doing WPF MVVM and have the following XAML code:
<TextBox Grid.Row="1" Name="Console" MinWidth="500" HorizontalAlignment="Stretch" AcceptsReturn="True" CharacterCasing="Upper" TextWrapping="WrapWithOverflow" Cursor="IBeam">
<TextBox.InputBindings>
<KeyBinding Command="{Binding Path=MyCommand}" CommandParameter="{Binding Text, ElementName=Console}" Key="Enter"/>
</TextBox.InputBindings>
</TextBox>
When handling the Enter press in the ViewModel's command property (initialized in constructor with event handler added):
private readonly MyCommand myCommand;
public ICommand MyCommand
{
get
{
return myCommand;
}
}
private void OnCommand(object sender, MyCommandEventArgs e)
{
<do something>
}
The event handler is called allright, but the Enter keypress is never passed back to the TextBox and the newline is not added (the cursor stays on the same line).
Doesn't event bubbling ensure that the Enter keypress gets passed on to the TextBox?

Could you just add "\n" to your textbox' Text-value?
(Would have add that as a comment but I may not do that yet...)

Related

Binding Text Change Event to prevent invalid input WPF XAML

I am currently trying to prevent a user from inputting anything aside from numbers into a textbox.
I currently have a Textbox with a textchange event which calls a relay command. however I am not able to effect the textbox from the relay command.
I have tried directly settings the textbox.text and that has not worked, nor has trying to return the string.
Here is my code
XAML
<TextBox x:Name="TextBox" Margin="5,5,0,0" Grid.Column="1" Grid.Row="3" HorizontalAlignment="Left" Width="31" ">
<i:Interaction.Triggers>
<i:EventTrigger EventName="TextChanged">
<command:EventToCommand Command="{Binding TextBoxTextChanged,Mode=TwoWay}"
CommandParameter="{Binding Path=Text, ElementName=TextBox}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBox>
View Model
DaysBackTextChanged = new RelayCommand<string>(daysBackText =>
{
Func<string> function = () =>
{
if (!Regex.IsMatch(daysBackText, "[^0-9]+"))
{
//return TextBox.Text;
return "X";
}
else
{
return "Y";
}
};
});
Modify your XAML to add a PreviewTextInput event in the TextBox
PreviewTextInput="NumbersOnly"
Now,let's use Regex,shall we ?
using System.Text.RegularExpressions;
private void NumbersOnly(object sender, TextCompositionEventArgs e)
{
Regex regex = new Regex("[^0-9]+");
e.Handled = regex.IsMatch(e.Text);
}
Here e.Handeled is to prevent anything rather than numbers being typed.
Hope this works :)

Password change event behaviour not working properly in prism using mvvm

I am triggering password change event and command action
xaml
<PasswordBox VmWindow:PasswordHelper.Attach="True" Height="25" Width="180" HorizontalAlignment="Left"
FontFamily="Arial" FontSize="11" BorderBrush="#FF959BA0" TabIndex="2"
VmWindow:PasswordHelper.Password="{Binding Path=Password, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" >
<i:Interaction.Triggers>
<i:EventTrigger EventName="PasswordChanged">
<i:InvokeCommandAction Command="{Binding ChangePasswordCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</PasswordBox>
Password changed event code:
private static void PasswordChanged(object sender, RoutedEventArgs e)
{
PasswordBox passwordBox = sender as PasswordBox;
SetIsUpdating(passwordBox, true);
SetPassword(passwordBox, passwordBox.Password);
SetIsUpdating(passwordBox, false);
}
Command Action
public ICommand ChangePasswordCommand { get; private set; }
public LoginViewModel ViewModel { get; set; }
private void ExecuteChangePasswordCommand()
{
try
{
if (loginModel != null)
{
loginModel.LoginPassword = Password;
}
}
catch (Exception exception)
{
}
}
Problem:
What is happening intially when application loads i enter char in textbox the "Event fires first and then action which ok normal senario",but when i press second char "my Action fires first then trigger that is the problem"
I don't know weather it is predefined process or am i doing something wrong .Because according to me order should always Event,action not Action,event
Please let me know where i am wrong.
Finally after spending a lot of time i am able to solve the above problem with some additional changes
Add Reference of Microsoft.Expressions.Interactions
Add two refrences:
xmlns:i="clrnamespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:ei=http://schemas.microsoft.com/expression/2010/interactions
Done few changes in password box:
<PasswordBox VmWindow:PasswordHelper.Attach="True" Height="25" Width="180" HorizontalAlignment="Left"
FontFamily="Arial" FontSize="11" BorderBrush="#FF959BA0" TabIndex="2"
VmWindow:PasswordHelper.Password="{Binding Path=Password, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" >
<i:Interaction.Triggers>
<i:EventTrigger EventName="PasswordChanged">
<ei:CallMethodAction TargetObject="{Binding}" MethodName="changePassword"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</PasswordBox>
Create a Method in Your LoginViewModel
public void changePassword(object sender, RoutedEventArgs e)
{
PasswordBox passwordBox = sender as PasswordBox;
loginModel.LoginPassword = passwordBox.Password;
}
Done With changes its clean MVVM with no code behind now

Eventhandler for WPF control in DataTemplate

I've been working with WPF and I have experienced a problem related with DataTemplates.
I have a view called DetailPage.xaml and this view uses a DataTemplate called Detail.xaml. I added a textbox to this DataTemplate and I want to handle the TextChanged event. So I made something like this:
<DataTemplate x:Name="DetailContent">
<Grid Margin="5" DataContext="{Binding Items[0]}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition MaxHeight="80"/>
</Grid.RowDefinitions>
<StackPanel Width="432">
<TextBox Name="NumeroParadaTB" Text="{Binding NumeroParada}" MaxLength="5" TextChanged="NumeroParadaTB_TextChanged" />
</StackPanel>
</Grid>
</DataTemplate>
Then I created and event handler in DetailPage.xaml.cs, like the following:
protected async void NumeroParadaTB_TextChanged(object sender, TextChangedEventArgs e)
{
string nroParada = ((TextBox)sender).Text;
if(!string.IsNullOrEmpty(nroParada) && nroParada.IsDigitsOnly() && nroParada.Length == 5)
{
}
}
But when running, and error is thrown saying that the event handler doesn't exist. I guess I'm using the eventhandler in a wrong way.
Thanks!
Since you're using data binding, I assume, that you have some class with NumeroParada property:
public class SomeClass : INotifyPropertyChanged
{
/* other code here */
public string NumeroParada
{
get { return numeroParada; }
set
{
if (numeroParada != value)
{
numeroParada = value;
OnPropertyChanged("NumeroParada");
}
}
}
private string numeroParada;
}
Setter of this property will fire, when UI will update the binding source. This is your "TextChanged" event.
Note, that by default, TextBox updates Text property, when loosing focus. If you want to perform any action when user changes text, update your binding definition:
Text="{Binding NumeroParada, UpdateSourceTrigger=PropertyChanged}"
So far so good. But this code:
if(!string.IsNullOrEmpty(nroParada) && nroParada.IsDigitsOnly() && nroParada.Length == 5)
suggests, that you're trying to implement validation of value, entered by user.
Validation in WPF is rather big theme, I'd recommend you to read something like this to select validation approach.
Instead of adding an Event handler, you can use Event to Command logic. Create a Command in ViewModel and bind it to the TextChanged event.
<TextBox Text="{Binding SearchText, Mode=TwoWay}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="TextChanged">
<i:InvokeCommandAction Command="{Binding MyCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBox>
Interaction triggers available in System.Windows.Interactivity assembly.

Textblock lostfocus event doesnt work as expected

I have a popup with listbox in it and this listbox is associated with a textbox.
Now while handling the lostfocus event for textbox, it works correctly when i try to click on other controls but the lostfocus doesnt get called when I try to click on window.Can somebody help me with this.
<TextBox x:name="txtbox1"/>
<Popup StaysOpen="False"
PlacementTarget="{Binding ElementName=txtbox1}"
Placement="Bottom">
<ListBox x:Name="CompanyListBox">
</Popup>
In constructor, I have txtbox1.LostFocus+="txtbox1_OnLostFocus"
private void txtbox1_OnLostFocus(object sender, RoutedEventArgs e)
{
if (string.IsNullOrEmpty(txtbox1.Text))
{
txtbox1.Text = DefaultFeature;
Popup.IsOpen = false;
}
}

How to pass parameters to an ICommand?

I defined an ICommand-Class ReadPersons which reads all person objects from the database with a particular where-clause.
The command is being executed trough pressing a button and the where-clause is being insert in a textbox.
Question: How can i pass the text from the textbox to the Execute-Command?
MainWindow.xaml:
<Button Command="{Binding ReadPersons}">Read persons</Button>
<TextBox Name="textBoxWhereClause" />
ReadPersons.cs:
public void Execute(object parameter)
{
// Read all persons with my where-clause
string whereClause = ??? //todo
}
Yes you can.
<Button Command="{Binding ReadPersons}"
CommandParameter="{Binding Text, ElementName=textBoxWhereClause}">
Read persons</Button>
<Button Command="{Binding ReadPersons}" CommandParameter="{Binding SomeProperty}" Content="Read Persons"/>

Categories

Resources