I need some advanced validation in WPF Richtextbox for flowdocuments, something like:
a) formatting can be applied only to the whole paragraph
b) no spans are allowed
c) these rules also need to be applied for Text pasted from clipboard.
What is the best way to do it?
Add an event handler to the textchanged event and apply whatever formatting you need done there. The event will fire no matter how the text is changed in the textbox (pasted via clipboard/entered from keyboard).
<RichTextbox x:Name="myTextbox" TextChanged="myTextbox_TextChanged"/>
private void myTextbox_TextChanged(object sender, EventArgs e)
{
//Apply formatting here
}
Edit: Alternatively if you're text is bound to some sort of datasource, you could implement data validation on the binding which will highlight the textbox red and ensure the users enters the desired input.
<RichTextbox x:Name="myTextbox" Text="{Binding TextSource, ValidatesOnExceptions=True}"/>
In the setter of the TextSource property you would throw an exception if the data entered does not meet your requirements.
Related
I have a WPF app where I'm updating output on key press.
My code works fine. Only it feels a little bit behind as I'm using KeyUp event.
When I try to use KeyDown, it is always a character behind. I have already tried adding UpdateSourceTrigger as shown in the TextBox XAML below
<TextBox
Text="{Binding TheLine, UpdateSourceTrigger=PropertyChanged}"
Behaviors:WatermarkTextBoxBehavior.EnableWatermark="True"
Behaviors:WatermarkTextBoxBehavior.Label="Please enter a numeric value"
Behaviors:WatermarkTextBoxBehavior.LabelStyle="{StaticResource watermarkLabelStyle}"
Grid.Column="0" x:Name="txtLengthFrom" GotFocus="txtLengthFrom_GotFocus" FontSize="15" FontWeight="SemiBold"></TextBox>
All characters are available as expected in the KeyUp event. What can I do to make sure all characters are available in the KeyDown event?
The code behind looks like this
public MainWindow()
{
InitializeComponent();
this.KeyDown += new KeyEventHandler(MainWindow_KeyDown);
}
void MainWindow_KeyDown(object sender, KeyEventArgs e)
{
UpdateOutput();
}
Based on #Jon's comment, I changed my code to use TextBox.TextChanged event and it works as I want. So now when I keep a key pressed, the output is changing as characters gets added to text box. The way I had it, it would not update the output while I had a key pressed. I just didn't like it so was trying to fix that.
KeyDown event happens before the key takes effect on your property. Not sure why you want to do this, but you'll need to check the KeyEventArgs for which key is being pressed if you HAVE to have them all in keydown. If you end up modifying your property based on what is in the KeyEventArgs, you'll need to set e.Handled = true to prevent it from happening twice (Since it will be handled later if you don't).
I'm hosting a WPF usercontrol in a windows form
In the wpf user control I am using a timepicker from wpfToolkit.extended
If I use the up or downkeys or just enter a time in the textfield the source is not updated allthough I am using Updatesourcetrigger = propertychanged.
When I select a time in the dropdrownlist everything works the way it should.
This is the namespace of the toolkit.
xmlns:xctk="clr-namespace:Xceed.Wpf.Toolkit;assembly=WPFToolkit.Extended"
This is the xaml for the timepicker
<xctk:TimePicker Format="LongTime" TimeInterval="00:15:00.000" Value="{Binding Path=StartTime, UpdateSourceTrigger=PropertyChanged}" ></xctk:TimePicker>
If I click outside the WPFusercontrol without changing the focus to another control in the wpf usercontrol first. The Binded time is not updated.
Any idea how I can fix this?
Found a solution for this problem:
I've given the TimePicker a name (In this case 'tpFrom') then I've used the TextBoxBase.TextChanged event on the TimePicker.
This is what the Xaml looks like now:
<xctk:TimePicker Name="tpFrom" Format="LongTime" TextBoxBase.TextChanged="TimePicker_TextChanged" TimeInterval="00:15:00.000" Value="{Binding Path=StartTime, UpdateSourceTrigger=PropertyChanged}"></xctk:TimePicker>
In the code behind in our eventhandler we'll put the focus on our timepicker.
private void TimePicker_TextChanged(object sender, TextChangedEventArgs e)
{
tpFrom.Focus();
}
Now everytime the text changes, the value changes as well and the problem is solved :-)
Does the TimePicker have a Text property? If so, try binding to that instead.
I think this behavior might be to prevent you from binding to a bad datetime as you type. I would guess that when focus is lost it tries to set the property and does error checking. If it did this while you typed it would constantly be changing the value anytime you make a change (say delete a character).
Is there something specific you are trying to do as you type?
Can anyone enlighten me to a way I can Highlight the content of an input field OnFocus preferably by XAML only?
So if a user bring focus to a field, it will highlight the string or whatever is in there so they can for example just tab to it, and replace the existing string as soon as they start typing instead of having to manually highlight and delete it first?
I've seen answers that require code, but wondering if there's a XAML only route? Thanks!
You can use AutoCompleteBox for this purpose and you won't have to write any code to acheieve this functionality. It already have this functionality and it will work as textbox too for you..
Let me know if you require any furter information.
Cheers!
Vinod
I highly doubt there would be XAML code that is equivalent to the TextBox.SelectAll() method.
It should be as easy as attaching each TextBox's GotKeyboardFocus event to a single event handler like this.
private void TextBox_GotKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
{
if (sender is TextBox)
((TextBox)sender).SelectAll();
}
<TextBox GotKeyboardFocus="TextBox_GotKeyboardFocus" />
I have a customer usercontrol that is a labeled TextBox (Border wrapped about a Label and a TextBox with the TextBox overlapping the label). I am finding few (working) examples on how to get the TextChanged function to work when called from my UserControl.
Just the textbox snippet:
<TextBox
FontSize="{Binding Path=DefaultFontSize}"
Style="{StaticResource WatermarkTextBox}"
Padding="{Binding Path=TextPadding}"
Tag="{Binding Path=TextValue}"
/>
I have tried using RoutedEventHandler like I did with my button's Click event, but it didn't work. How do I get it so when let's say I use on the window it is required:
<MyControl:LabeledTextBox
TextBoxChange="Some_Event"
TextValue="{Binding SomethingOrOther}"
/>
that it will fire off correctly and do the needed function
This question's really unclear. Do you want your user control to support a TextChanged event that gets raised when the text in the TextBox changes? If so, you need to implement it in the code-behind.
First, declare the event:
public event TextChangedEventHandler TextChanged;
Then, add an event handler to the TextBox:
<TextBox TextChanged="TextBox_TextChanged" ... />
and in the code-behind:
private void TextBox_TextChanged(object sender, TextChangedEventArgs args)
{
TextChangedEventHandler h = TextChanged;
if (h != null)
{
h(this, args);
}
}
If you are using MVVM (Or if your TextValue binding is binding to something you can get to and edit) you can put the logic you want executed in the setter.
So, lets say you are binding to a property MyTextBoxValue. Set the binding mode to two way in the XAML, and in the setter put the logic or call to another method.
If you want the code to fire every time you type, set UpdateSourceTrigger=PropertyChanged in XAML, if you want the code to fire only when text entry is "done" set UpdateSourceTrigger=LostFocus.
I have a Grid with many TextBoxes and I want to call NotifyPropertyChanged() method to update some other controls everytime one of these TextBox-es changed the value = lost the focus (I don't want to use PropertyChanged as UpdateSourceTrigger)
This is what I can do:
<Grid TextBoxBase.TextChanged="My_TextChanged" >
...
</Grid>
I need something like:
TextBoxBase.OnLostFocus
Use the lost focus event
TextBox.LostFocus="OnTextBoxLostFocus"
Filter on textboxes ;)
private void OnTextBoxLostFocus(object sender, RoutedEventArgs e)
{
if(!(e.OriginalSource is TextBox))
return;
//Do stuff
}
If your properties are not changed, your Textboxes will not be updated however. You should consider mutating the data those other TextBoxes are bound to, instead of using LostFocus to update your model.
Good luck!
TextBoxBase.LostFocus is, I suspect, the event you're looking for.
It's listed here: http://msdn.microsoft.com/en-us/library/system.windows.controls.primitives.textboxbase_events.aspx - but it's defined on UIElement - so you possibly want to try UIElement.LostFocus if the above doesn't work in markup.