I created a TextBox. I wrote a TextChanged event in view model. The problem is, when I type 'a' in the TextBox, in the TextChanged event, I am getting "". Then if I type next letter 'b', I am getting the previous result 'a' and If I type the next letter 'c', I am getting 'ab' as result. Why is one char delay in the TextChanged event?
Here is my XAML code:
<toolkit:PhoneTextBox Visibility="{Binding IsSearchBoxVisible,Converter={StaticResource BoolToVisibilityConverter}}" TextChanged="txtboxPhoneContacts_TextChanged" Grid.Row="2" Width="450" FontSize="28" Foreground="Black" x:Name="txtboxPhoneContacts" VerticalContentAlignment="Center" Background="LightGray" Hint="{Binding Localizedresources.SearchContactsText,Source={StaticResource LocalizedStrings}}" Text="{Binding PhoneContactSearchText,Mode=TwoWay,UpdateSourceTrigger=Explicit}" Style="{StaticResource SearchTextBoxStyle}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="TextChanged">
<i:InvokeCommandAction Command="{Binding PhoneBookTextBoxTextChanged}" CommandParameter="{Binding Text,ElementName=txtboxPhoneContacts,BindsDirectlyToSource=True}"></i:InvokeCommandAction>
</i:EventTrigger>
</i:Interaction.Triggers>
<i:Interaction.Behaviors>
<controls:UpdateOnTextChangedBehavior></controls:UpdateOnTextChangedBehavior>
</i:Interaction.Behaviors>
</toolkit:PhoneTextBox>
My ViewModel.cs
private void OnPhoneBookTextBoxTextChanged(Object obj)
{
if (obj != null)
{
String text = obj.ToString();
searchResults = new ObservableCollection<PhoneBookEntity>(
from item in PhoneContactsList
where item.PhoneContactName.Contains(text)
select item);
}
}
Any suggestions is highly appreciated.
Related
I have editable combobox in WPF. which is having list of order number.
I need to implement below scenario in my code.
The user can fill the starting of order number, and, the system propose the close order number available in the dropdown list.
Can anyone suggest how to do that?
In My Viewmodel i have written:
public void _fillREOrderNumbers()
{
List<FinishedReprintingOrderNumber> orders = _finishedProductReprintService.GetFinishedProductReprintbyOrder().ToList();
foreach (var item in orders)
{
ReOrders.Add(item);
}
}
This is loading the order number in drop down.
View or XAML:
<ComboBox x:Name="cbOFab" HorizontalAlignment="Left" Margin="373,81,0,0"
VerticalAlignment="Top" Width="262" IsEditable="True"
ItemsSource="{Binding ReOrders, Mode=TwoWay}" DisplayMemberPath="codOrder" SelectedItem="{Binding
ReSelectedOrder}" Background="{DynamicResource dgridRowColor}" />
Till Now,
I am able to populate the order number in my combo box but I am not aware how to search inside it.
I have implemented filtering of items in ComboBox this way.
Here is XAML:
<ComboBox
MinWidth="200"
ItemsSource="{Binding Path=Shops.View, RelativeSource={RelativeSource TemplatedParent}}"
DisplayMemberPath="NameExtended"
SelectedItem="{Binding Path=SelectedShop, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"
IsTextSearchEnabled="False"
IsEditable="True"
IsDropDownOpen="{Binding Path=ComboOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"
StaysOpenOnEdit="True"
Text="{Binding Path=SearchText, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"
>
<i:Interaction.Triggers>
<i:EventTrigger EventName="KeyUp">
<i:InvokeCommandAction
Command="{Binding Path=FilterCommand, RelativeSource={RelativeSource TemplatedParent}}"
/>
</i:EventTrigger>
</i:Interaction.Triggers>
You need all lines from IsTextSearchEnabled and below.
When you press any key in combo box, it opens in up and filters items in it, using property SearchText bound to ComboBox.Text.
Here is the view model code:
public string SearchText { get; set; }
private List<Shop> _shops;
protected void FilterShops()
{
ComboOpen = true;
if (!string.IsNullOrEmpty(SearchText))
{
Shops.UpdateSource(_shops.Where(s => s.NameExtended.ToLower().Contains(SearchText.ToLower())));
}
else
{
Shops.UpdateSource(_shops);
}
OnPropertyChanged("Shops");
}
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 :)
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
I want to raise event using MouseLeftButtonDown by clicking on a date in Calendar Control. But it is not raised until I click outside of this component.
Here is the xaml code:
<Controls:BasicCalendar Grid.Row="0"
x:Name="DemoCalendar"
DisplayDate="{Binding Path=DisplayDate, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
HighlightedDateText="{Binding HighlightedDateText, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Grid.Column="0"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Margin="0,0,0,0"
DateHighlightBrush="Gold">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseLeftButtonDown">
<cal:ActionMessage MethodName="CalendarSelectDateEvent">
<cal:Parameter Value="{Binding ElementName=DemoCalendar, Path=SelectedDate}" />
</cal:ActionMessage>
</i:EventTrigger>
</i:Interaction.Triggers>
</Controls:BasicCalendar>
Here is the event which I want to raise after clicking on some date in calendar:
public void CalendarSelectDateEvent(DateTime selectedDate)
{
this.ActualCalendarEvents = this.CalendarEvents.Where(x => x.Date >= selectedDate).ToList();
var a = this.ActualCalendarEvents;
this.ActualCalendarEvents = null;
NotifyOfPropertyChange(() => ActualCalendarEvents);
this.ActualCalendarEvents = a;
NotifyOfPropertyChange(() => ActualCalendarEvents);
}
When I tried to use Click event instead of MouseLeftButtonDown the Calendar Control was automatically handling it without firing CalendarSelectDateEvent. Is there a way to fire both events? (For Calendar Control selecting and highlighting the dat and for me CalendarSelectDateEvent)
I already figured it out. It was really easy in the end. The Calendar Control has property SelectedDate. I just binded SelectedDate to my property SelectedDateChanged in code behind and when the SelectedDate changed I raise the event CalendarSelectDateEvent.
<Controls:BasicCalendar Grid.Row="0"
x:Name="DemoCalendar"
DisplayDate="{Binding Path=DisplayDate, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
HighlightedDateText="{Binding HighlightedDateText, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Grid.Column="0"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Margin="0,0,0,0"
SelectedDate="{Binding SelectedDateChanged}"
DateHighlightBrush="Gold">
</Controls:BasicCalendar>
Like this:
public DateTime SelectedDateChanged
{
get
{
return selectedDateChanged;
}
set
{
this.selectedDateChanged = value;
this.CalendarSelectDateEvent(this.selectedDateChanged);
}
}
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"/>