How to use LostFocus in Caliburn Micro - c#

I need to validate the value in the text box when the users finish their input.
When they go to the next text box, the previous text box will validate the range of input (100~100000 steps 100 and format is "###,###"). And my opinion is Lost Focus Event is the good way to solve this.
I have this property which I want to use Lost Focus
private string resultCommandNote02;
public string ResultCommandNote02
{
get
{
return resultCommandNote02;
}
set
{
resultCommandNote02 = value;
NotifyOfPropertyChange(() => ResultCommandNote02);
}
}
And here is the code of View.XAML
<TextBox Grid.Column="1" Margin="0 0 0 4" Text="{Binding ResultCommandNote01}"
cal:Message.Attach="[Event LostFocus] = [Action TxtCmdNote01_LostFocus]"></TextBox>

Related

WPF - Strange behaviour of TextBox when disabling from view model

I have this xaml code in user control:
<StackPanel Orientation="Horizontal" IsEnabled="{Binding CanEditOpenCut}">
<TextBox Text="{Binding OpenCut}" Margin="5" Width="80"/>
<TextBlock Text="°C" />
</StackPanel>
And I have viewmodel with properties:
private decimal _openCut;
public decimal OpenCut
{
get
{
return _openCut;
}
set
{
if (Set(ref _openCut, value))
{
RaisePropertyChanged(() => OpenCut);
if (this.PrevRunConfig != null)
{
this.PrevRunConfig.CloseCut = _openCut;
}
}
}
}
private bool _canEditOpenCut;
public bool CanEditOpenCut
{
get
{
return _canEditOpenCut;
}
set
{
if (Set(ref _canEditOpenCut, value))
{
}
}
}
Now the binding works fine when I set in textbox e.g. 40 then I have it in my OpenCut property in viewmodel. If I set something in viewmodel I get it in the textbox. So far its working. Now I try to disable the textbox and reset the value to some default like 20. There are 2 scenarios one is working and one not.
1) If I set e.g. 40 in textbox, then lose focus and then set CanEditOpenCut = false and OpenCut = 20, everything works I see 20 in textbox.
2) I set 40 to the textbox, I DO NOT !!! lose focus of the textbox, then I set CanEditOpenCut = false and OpenCut = 20. Now it is not working I still see 40 in textbox although the values in viewmodel are correct.
Thanks for any help,
Tomas

WPF Focus after Command - Why does it land on my Window?

I am trying to make a small modal window with a search box and a list of results.
My goal is for the focus to land in the first element of the List after searching.
Problem
Unfortunately, I stuck in a situation where my focus lands on the window itself after searching.
My TextBox has an InputBinding that triggers on enter to perform the search:
<TextBox Grid.Column="1" Grid.Row="1"
Text="{Binding Supplier.LeverandorNavn, UpdateSourceTrigger=PropertyChanged}"
x:Name="txtBoxSupplierName" Width="150"
HorizontalAlignment="Left" VerticalAlignment="Top"
TabIndex="1">
<TextBox.InputBindings>
<KeyBinding Key="Return" Command="{Binding SearchCommand}" />
</TextBox.InputBindings>
</TextBox>
I have been trying to use Snoop to understand the flow of events.
As seen here, the KeyDown is handled by my txtBoxSupplerName Textbox fine.
But I cannot understand why the levWindow gets focus after my command executes.
I have attempted to manually set the focus element, but it has no effect.
Questions
Can someone explain to me, why the focus lands on the window by default?
Can someone suggest an approach, on how I can take control of the focus myself and avoid this default behavior?
I am challenged by the fact that the DataGrid needs some time to redraw itself before the row I want to focus is visible.
Properties
public ClientLeverandor ValgtLeverandør
{
get { return _valgtLeverandør; }
set { SetProperty(ref _valgtLeverandør, value, nameof(ValgtLeverandør)); }
}
public ObservableCollection<ClientLeverandor> Leverandører
{
get { return _leverandører; }
private set { SetProperty(ref _leverandører, value, nameof(Leverandører)); }
}
public ListCollectionView LeverandørView
{
get { return _leverandørView; }
set { SetProperty(ref _leverandørView, value, nameof(LeverandørView)); }
}
Command Implementation
using (BusyIndicator.ShowInScope(Strings.HenterData_BusyText))
{
var leverandører = await SøgLeverandører(Supplier);
if (leverandører.Any())
{
Leverandører.Clear();
foreach (var lev in leverandører) Leverandører.Add(lev);
ValgtLeverandør = Leverandører[1];
SuppliersAdded?.Invoke();
}
}
I was unable to find an explanation for why KeyboardFocus land on my window or why my attempts to set the focus did not have effect.
But i was finally able to find a solution, where my attempt worked.
I used a Dispatcher with BackgroundPriority to invoke my method to set focus after whatever was setting focus to the window. This worked for both Keyboard and Mouse input.
private void ViewModel_SuppliersAdded()
{
Dispatcher.BeginInvoke(new Action(SetFocusToFirstRow), DispatcherPriority.Background);
}

c# wpf textbox - adding a text to input TextBox

I want to add percent sign "%" to any input text in wpf TextBox when the user insert a text.
So when the user will enter a number, will be added % sign to any number in the input box,
for example: 5 will shown at the Text box as 5%
0 - 0%
100 - 100%
I tried the following code:
<TextBox x:Name="TextBoxInputValue" Text="{Binding AddPercentSign, UpdateSourceTrigger=PropertyChanged, StringFormat={}{0}%}" Style="{StaticResource #TextBoxStyle}" Width="100" Height="20"></TextBox>
and:
public int AddPercentSign{ get; set; }
and:
TextBoxInputValue.DataContext = this;
But it has no effect on the TextBox when the user insert an input...
How can I achieve that result?
Thank you
You could use a flag that decides whether you should actually set the Text property in the event handler:
private bool _handleEvent = true;
private void TextChanged(object sender, TextChangedEventArgs e)
{
if (_handleEvent)
{
_handleEvent = false;
MyTextBox.Text = MyTextBox.Text + "%$#";
_handleEvent = true;
}
}
If you are binding your Text property, you can use StringFormat.
<TextBox Text="{Binding SomeProperty, StringFormat={}{0}%}" />
Check out this tutorial.
But it has no effect on the TextBox when the user insert an input...
You need to define the source property and set the DataContext of the TextBox to the class where it is defined, e.g.:
<TextBox x:Name="textBox1" Text="{Binding SomeProperty, UpdateSourceTrigger=PropertyChanged, StringFormat='{}{0}%'}" />
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
textBox1.DataContext = this;
}
public int SomeProperty { get; set; }
}
Checkout this link, even I was facing somewhat similar problem
Solution in this link can me modified according to your condition.
Add percent sign "%" to any input text in wpf TextBox when the user insert a text

Xaml How to Enable/Disable and Validate text item in one time

Using MVVM, Devexpress WPF, c#
For example I have two items in a view (I have more in real project) and using them for user to enter some search paramaters and need to validate them and the same time disable another one, if something is written in the first field and overwise.
What I do, I use Validate to determ the Lenght of value and I need to Enable/Disable even if lenght of entered text doesn't meet required lenght
View
Xaml:
<dxe:TextEdit
Text="{Binding SearchField1, UpdateSourceTrigger=PropertyChanged}"
Validate="searchFieldValidate"/>
<dxe:TextEdit
IsEnabled="{Binding IsTextItemEnabled}"
Text="{Binding SearchField2, UpdateSourceTrigger=PropertyChanged}"
Validate="searchFieldValidate"/>
c#
private void searchFieldValidate(object sender, DevExpress.Xpf.Editors.ValidationEventArgs e)
{
if (e.Value == null) return;
if (e.Value.ToString().Length > 5) return;
e.IsValid = false;
e.ErrorType = DevExpress.XtraEditors.DXErrorProvider.ErrorType.Warning;
e.ErrorContent = "Enter more than 5 symbol";
}
ViewModel
Here I set IsTextItemEnabled depending on is value empty or mot
public string SearchField1
{
get { return _searchField1; }
set
{
if (value != _searchField1)
{
_searchField1 = value;
if (!String.IsNullOrEmpty(value))
IsTextItemEnabled = false;
else
IsTextItemEnabled = true;
RaisePropertiesChanged("SearchField1");
}
}
}
A problem is that RaisePropertiesChanged doesn't work until field lenght doesn't reach 5 symbols
Could You please help me to solve this problem? First of all I am trying to Disable one field, so I use one bool IsTextEnabled.. what about oposite variant...
I gave names to TextEdit
<dxe:TextEdit
Name="txtEdit1"
Text="{Binding SearchField1, UpdateSourceTrigger=PropertyChanged}"
Validate="searchFieldValidate"/>
<dxe:TextEdit
Name="txtEdit2"
Text="{Binding SearchField2, UpdateSourceTrigger=PropertyChanged}" />
and add a line to validate procedure:
txtEdit2.IsEnabled = String.IsNullOrEmpty(e.Value?.ToString());
So now I am able to validate and enable/disable at one time.. Don't use OnPropertiesChanged this time

How to clear textbox on click button [duplicate]

This question already has answers here:
How to clear text box on click in MVVM
(2 answers)
Closed 7 years ago.
I have a textbox in which I am handling its text changed event.Now when I click button I want to clear the text from the textbox.
Now when I have text in the textbox and when I call my command the text is not cleared.
xaml
<TextBox Text="{Binding SearchText,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}" Name="mytxtBox">
<TextBox.InputBindings>
<KeyBinding Command="{Binding Path=SearchCommand}" CommandParameter="{Binding ElementName=mytxtBox, Path=Text}" Key="Enter"/>
</TextBox.InputBindings>
</TextBox>
ViewModel
public string SearchText
{
get
{
return TypedText;
}
set
{
TypedText=value;
if (string.IsNullOrEmpty(TypedText.ToString()))// This is called when the text is empty
{
Some Logic//
}
SetProperty(ref TypedText, value);
}
}
private void MyCommandExecuted(string text)
{
SearchText= string.Empty;
}
You seem not to understand the framework you are using
public string SearchText
{
set
{
TypedText = value;
SetProperty(ref TypedText, value);
}
}
These two lines of code should/could NEVER ever be in the same block of code EVER.
What is happening is this.
The first line sets TypedText to value. OKAY...
Second line, check if TypedText is equal to value (spoiler alert, it is), and set them to be equal if not AND THEN TELL WPF that you changed to value.
The problem is, the second line never runs its logic (of tell WPF that I've changed). The reason this never runs is the first line.
Remove TypedText = value; from your code and it might just work.
set
{
if (string.IsNullOrEmpty(value))// This is called when the text is empty
{
Some Logic//
}
SetProperty(ref TypedText, value);
}
However, one last thing. I really really really hate code where the setter DOES stuff. Why is there logic here? From an external user, it might do something unexpected.
I have a textbox in which I am handling its text changed event
No you don't, or at least not in the code excerpt that you have shown in your question:
<TextBox Text="{Binding SearchText, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" Name="mytxtBox">
<TextBox.InputBindings>
<KeyBinding Command="{Binding Path=SearchCommand}" CommandParameter="{Binding ElementName=mytxtBox, Path=Text}" Key="Enter"/>
</TextBox.InputBindings>
</TextBox>
In this example, you have a string property data bound to the TextBox.Text property, which is similar, but not the same as handling its text changed event.
Either way, in order to clear this data bound value, you just need to set your data bound string property to an empty string (after removing that extraneous code from the setter):
public string SearchText
{
get { return TypedText; }
set { TypedText = value; SetProperty(ref TypedText, value); }
}
...
private void MyCommandExecuted(string text)
{
SearchText = string.Empty;
}

Categories

Resources