AutocompleteBox validation - c#

I have an autocomplete box in silverlight and it is bound to a collection. It is working fine. I just want it so that the user can't enter any values which are not in the collection.
For example: Collection contain a value "Head". If user Enters Headx or something other than that, a validation should be fired.
how to do this?
Regards
Arun

try with this
<Sdk:AutoCompleteBox Grid.Column="3" Grid.Row="3" Height="18" Width="150"
IsTextCompletionEnabled="True" TabIndex="9" HorizontalAlignment="Left"
Text="{Binding ElementName=ResEdit,Path=DataContext.SelectedDemoText,Mode=TwoWay}"
ItemsSource="{Binding ElementName=ResEdit,Path=DataContext.DemoList,Mode=OneWay}"
ItemTemplate="{StaticResource DemoTemplate}"
ValueMemberPath="DemoCode"
LostFocus="AutoCompleteBox_LostFocus"
Margin="0,0,21,0" Padding="0">
</Sdk:AutoCompleteBox>
You should not use both function SelectedText and SelectedItem in autocomplete. it's a bug of AutoCompleteBox..... A better way is to set the visiblity of the textbox and AutoCompleteBox on GotFocus and LossFocus. This Way You Will Defiantly Solve You Problem
private void DemoAutoComplete_LostFocus(object sender, RoutedEventArgs e)
{
DemoTextBox.Visibility = Visibility.Visible;
DemoAutoComplete.Visibility = Visibility.Collapsed;
DemoTextBox.Text = OCRAutoComplete.Text;
((DemoVM)this.DataContext).SelectedDemoText = DemoAutoComplete.Text;
}
private void DemoTextBox_GotFocus(object sender, RoutedEventArgs e)
{
DemoAutoComplete.Text = OctTextBox.Text;
DemoTextBox.Visibility = Visibility.Collapsed;
DemoAutoComplete.Visibility = Visibility.Visible;
DemoAutoComplete.Focus();
}

You should just be able to change your Binding to achieve this.
By default text properties usually update the Binding source when the control loses focus. By setting the Binding to update the source on PropertyChanged, you can implement validation with each keystroke.
Your Binding on the Text property would look something like this
Text="{Binding MyProperty, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
In your property setter you can then throw a ValidationException when you deem it appropriate, or you can implement one of the validation interfaces (INotifyDataErrorInfo or IDataErrorInfo) and deal with it that way.
This article is a good source of info about the complexities of data Binding

I have recently worked on this. My problem is solved by checking
the selected item property on the lost focus event of the autocomplete box.
private void autoCompleteBox1_LostFocus(object sender, RoutedEventArgs e)
{
if (autoCompleteBox1.SelectedItem == null && !string.IsNullOrEmpty(autoCompleteBox1.Text))
{
MessageBox.Show("Please fill in the right value");
autoCompleteBox1.Text = "";
autoCompleteBox1.Focus();
}
}
Regards
Priya

Related

C# / WPF Unmask password inside the passwordBox

How could I unmasked and masked the password inside the passwordBox whenever I click the checkBox? I'm using C# WPF template.
Here is my .XAML code:
<PasswordBox x:Name="passwordBox_password" Grid.Row="2" Grid.Column="1" Grid.ColumnSpan="2" Margin="5" Height="25" />
<CheckBox x:Name="checkBox_showPassword" Grid.Row="3" Grid.Column="1" Margin="5,0,5,5" Content="show password" Checked="checkBox_showPassword_Checked" Unchecked="checkBox_showPassword_Unchecked" />
Here is my .CS code:
private void checkBox_showPassword_Checked(object sender, RoutedEventArgs e)
{
// what to do here ?
}
private void checkBox_showPassword_Unchecked(object sender, RoutedEventArgs e)
{
// what to do here ?
}
Or is there another way to do it in WPF?
It's very simple to do that.
First you should to add the value PasswordChar in your PasswordBox:
<PasswordBox Name="PasswordHidden" PasswordChar="•"/>
Next under the PasswordBox tag you should to add a TextBox with Visibility value setted to Hidden:
<TextBox Name="PasswordUnmask" Visibility="Hidden"/>
And a trigger to show / hide the password, for example a simple text or a button. In my case I'm using a simple text.
<TextBlock Name="ShowPassword"/>
Next you need to add 3 different events in the trigger element, for example (this is valid for TextBlock or Image, if you want to use a Button you should to choose another events):
<TextBlock x:Name="ShowPassword" Text="SHOW" PreviewMouseDown="ShowPassword_PreviewMouseDown" PreviewMouseUp="ShowPassword_PreviewMouseUp" MouseLeave="ShowPassword_MouseLeave"/>
The events are PreviewMouseDown PreviewMouseUp and MouseLeave but you can choose the appropriate event for your situation.
Now in your code you need to program the functions:
private void ShowPassword_PreviewMouseDown(object sender, MouseButtonEventArgs e) => ShowPasswordFunction();
private void ShowPassword_PreviewMouseUp(object sender, MouseButtonEventArgs e) => HidePasswordFunction();
private void ShowPassword_MouseLeave(object sender, MouseEventArgs e) => HidePasswordFunction();
private void ShowPasswordFunction()
{
ShowPassword.Text = "HIDE";
PasswordUnmask.Visibility = Visibility.Visible;
PasswordHidden.Visibility = Visibility.Hidden;
PasswordUnmask.Text = PasswordHidden.Password;
}
private void HidePasswordFunction()
{
ShowPassword.Text = "SHOW";
PasswordUnmask.Visibility = Visibility.Hidden;
PasswordHidden.Visibility = Visibility.Visible;
}
The following link will bring you to the answer you are looking for my good sir. Mr Lamas did a great job of answering the how-to so I'd rather redirect you to the answer :)
showing password characters on some event for passwordbox
I recommend Using MahApps.Metro ... after installing it from nuget.org ... you must use it in the head of your xaml like this
xmlns:controls="http://metro.mahapps.com/winf/xaml/controls"
and then ... just use it's style for your PasswordBox control
<PasswordBox Style="{StaticResource MetroButtonRevealedPasswordBox}" />
you can even change the content for the show icon using the controls:PasswordBoxHelper.RevealButtonContent attached property

checkbox event not firing when unchecked

Simple question over here.
Pretty simple code too.
I have a checkbox and I also have a combobox.
Basically the combobox's selected item should change whenever the the checkbox is ticked or unticked.That's not going so well right now.
It works when it's going from uncheked to checked, but when I uncheck it, the combobox value stays the same.
Checkbox Code:
private void linked_Checked(object sender, RoutedEventArgs e)
{
if (linked.IsChecked == true)
{
Chained.SelectedIndex = 0;
}
if (linked.IsChecked == false)
{
Chained.SelectedIndex = 1;
}
}
Combobox Code:
<ComboBox x:Name="Chained" Text="{Binding Chained, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Margin="128,69,132,-92" Grid.Row="15" Visibility="Visible" SelectionChanged="Chained_SelectionChanged" >
<ComboBoxItem Content="True"/>
<ComboBoxItem Content="False"/>
</ComboBox>
This should be pretty straight forward right? So where am I going wrong?
If there's a way to do this in xaml then I'm all ears too.
Put it inside Unchecked event,
private void linked_UnChecked(object sender, RoutedEventArgs e)
{
if (linked.IsChecked == false)
{
Chained.SelectedIndex = 1;
}
}
The reason is when the checked event is fired, the state is not changed yet and this happends before the new value get set. It means when the event is fired you are still getting the old value. So I always find CheckStateChanged event much better . Because this event is fired when the check state is changes. so then you can say something like this.
private void checkBox1_CheckStateChanged(object sender, EventArgs e)
{
if (linked.CheckState == CheckState.Checked){
Chained.SelectedIndex = 0;
}
}

Combobox refresh gives Value '' couldn't be converted validation error

i'm new to WPF. I have an application with multiple tabs. In one tab I can insert data into a table in the database. In another tab I have a combobox with itemsource of the table mentioned earlier. I want to update the combobox items when user want to chose from the combobox./
I tried with the GotFocus property in the following way:
private void ComboBoxOperatingPoints_GotFocus_1(object sender, RoutedEventArgs e)
{
this.ThisViewModel.UpdateModel();
}
Updatemodel function contains the following:
this.OperatingPoints = new ObservableCollection<Operating_Point>(new OperatingPointRepository().GetAll());
this.NotifyPropertyChanged("OperatingPoints");
The combobox bindind in the XAML :
<ComboBox SelectionChanged="ComboBoxOperatingPoints_SelectionChanged"
x:Name="ComboBoxOperatingPoints"
GotFocus="ComboBoxOperatingPoints_GotFocus_1"
FontSize="30"
HorizontalAlignment="Right"
Margin="40,40,0,0"
VerticalAlignment="Top"
Width="200"
Height="50"
IsSynchronizedWithCurrentItem="True"
ItemsSource="{Binding OperatingPoints}"
DisplayMemberPath="name"
SelectedValue="{Binding OperatingPointID,UpdateSourceTrigger=PropertyChanged}"
SelectedValuePath="operating_point_id"
>
The combobox refresh, but gives validation error and I can't use it anymore after the first GotFocus event occured.
Thanks in advance!
EDIT:
Finaly I changed the GotFocus event to DropDownOpened event and it's working fine.
Your code is creating a new ObservableCollection on every update. You probably only want to create the ObservableCollection once, then replace it's contents in UpdateModel. So, for example, in your view model's constructor, instantiate the OperatingPoints collection:
public class MyViewModel {
public MyViweModel() {
this.OperatingPoints = new ObservableCollection<Operating_Point>();
}
}
Then, in UpdateModel:
public void UpdateModel() {
this.OperatingPoints.Clear();
foreach ( Operating_Point point in new OperatingPointRepository().GetAll() ) {
this.OperatingPoints.Add(point);
}
NotifyPropertyChanged( "OperatingPoints" );
}

What is the correct way to code the nested methods?

I have created a registration form in silverlight 4, where i have a large number of text-boxes, in front of each text box i have placed a text-block as a required field validator, when any of the textbox left empty while loosing focus, the textblock placed in front of it must become red.
textboxes named textbox1, textbox2 ... and so as the textblocks
the problem is, i do not want code the specific method for each specific textbox, all i want to do is to complete such in just two three methods
here i did some coding which doesn't seems to be correct
private void textBox_LostFocus(object sender, RoutedEventArgs e)
{
var textBox = (TextBox) sender;
if (textbox.Text == "")
{
var textblock = "textblock" + textBox.Name.Remove(0,7);
TextblockColorChange(textblock);
}
}
private void TextblockColorChange(object sender)
{
var textblock = (TextBlock) sender;
textblock.Foreground= new SolidColorBrush(Colors.Red);
}
please suggest some better way to do so..
I'd create a UserControl that contains the TextBlock and the TextBox and use this UserControl everywhere you currently have the TextBlock and TextBox combination. Then this Usercontrol would have the LostFocus logic inside it and update the TextBlock appropriately. This prevents the need to figure out the right name of the control to update.
you need something like this,
XAML part:
<Grid x:Name="LayoutRoot" Background="White">
<StackPanel Orientation="Horizontal" Height="25">
<TextBox Width="150" LostFocus="TextBox_LostFocus"/>
<TextBlock Text="*" Foreground="#FF0000" VerticalAlignment="Center" Margin="10,0,0,0" Visibility="Collapsed"/>
</StackPanel>
</Grid>
C# Part:
private void TextBox_LostFocus(object sender, RoutedEventArgs e)
{
var textbox = sender as TextBox;
if(textbox == null) return;
var stackPanel = textbox.Parent as StackPanel;
if(stackPanel == null) return;
var textBlock = stackPanel.Children.Where(a => a is TextBlock).FirstOrDefault();
if (textBlock == null) return;
if (string.IsNullOrEmpty(textbox.Text)) textBlock.Visibility = Visibility.Visible;
else textBlock.Visibility = Visibility.Collapsed;
}
Whilst I actually prefer Bills approach (although I'd be inclined to use a Templated Control) here is another alternative which is quite fun. In your xaml use this sort of markup:-
<TextBlock Text="Enter Value 1" Foreground="{Binding Tag, ElementName=textBox1, TargetNullValue=Black}" />
<TextBox x:Name="textBox1" LostFocus="txt_LostFocus" />
Your common txt_LostFocus can look like this:-
private void txt_LostFocus(object sender, RoutedEventArgs e)
{
TextBox txt = ((TextBox)sender);
if (String.IsNullOrEmpty(txt.Text))
{
txt.Tag = new SolidColorBrush(Colors.Red);
}
else
{
txt.Tag = null;
}
}
var textblock = "textblock" + textBox.Name.Remove(0,7);
TextblockColorChange(textblock);
This code above will just send a string to TextblockColorChange()
You don't show any other code, but I'm guessing you want to do a FindControl or FindControl like search on that string before passing the result to your code.

in Silverlight DataGrid, CheckBox's DataContext sometimes null when Checked/Unchecked

I have a DataGrid. One of the columns is a template with a CheckBox in it. When the Checked or Unchecked events trigger, (it happens with both) the CheckBox's DataContext is sometimes null, which causes my code to error. It seems to be null most often if the mouse is moving while you press and release the button quickly (it's intermittent).
I listened for changes to the DataContext of the CheckBox by making views:ListenCheckBox (extends CheckBox) and attaching a binding, and it's never set to null, but it is set from null to a Task at times I wouldn't expect, i.e. after the DataGrid has been totally generated and you're checking/unchecking boxes. Immediately after the [un]checked event runs with a null DataContext, I get the notification that shows the DataContext changed from null to a Task, so it appears that when I get a null DataContext, it's because it hadn't actually set the DataContext by the time it ran the Checked/Unchecked event.
Also, I added Tag="{Binding}" to the CheckBox for debugging. The Tag is not null (i.e. it has the proper object) more often than the DataContext, but still not all the time.
Here are the relevant bits of the XAML code:
<navigation:Page.Resources>
<sdk:DataGridTemplateColumn x:Key="DeleteOrPrintSelect" Header="Delete Or Print Notes Selection">
<sdk:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<views:ListenCheckBox IsChecked="{Binding DeleteOrPrintNotesSelection, Mode=TwoWay}" Checked="DeletePrintNotesCheckBox_Changed" Unchecked="DeletePrintNotesCheckBox_Changed" HorizontalAlignment="Center" VerticalAlignment="Center" Tag="{Binding}" />
</DataTemplate>
</sdk:DataGridTemplateColumn.CellTemplate>
</sdk:DataGridTemplateColumn>
</navigation:Page.Resources>
<sdk:DataGrid x:Name="dataGrid1" Grid.Column="1" Grid.Row="2" AutoGeneratingColumn="dataGrid1_AutoGeneratingColumn">
<sdk:DataGrid.RowGroupHeaderStyles>
[removed]
</sdk:DataGrid.RowGroupHeaderStyles>
</sdk:DataGrid>
And the relevant code behind:
// Create a collection to store task data.
ObservableCollection<Task> taskList = new ObservableCollection<Task>();
[code adding Tasks to taskList removed]
PagedCollectionView panelListView = new PagedCollectionView(taskList);
this.dataGrid1.ItemsSource = panelListView;
}
private void dataGrid1_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
if (e.PropertyName == "DeleteOrPrintNotesSelection")
{
e.Column = Resources["DeleteOrPrintSelect"] as DataGridTemplateColumn;
}
else
{
e.Column.IsReadOnly = true;
}
}
private void DeletePrintNotesCheckBox_Changed(object sender, RoutedEventArgs e)
{
try
{
var cb = sender as CheckBox;
var t = cb.DataContext as Task;
t.DeleteOrPrintNotesSelection = cb.IsChecked == true;
PagedCollectionView pcv = this.dataGrid1.ItemsSource as PagedCollectionView;
ObservableCollection<Task> taskList = pcv.SourceCollection as ObservableCollection<Task>;
bool anySelected = taskList.Any(x => x.DeleteOrPrintNotesSelection);
this.btnPrint.IsEnabled = anySelected;
this.btnDelete.IsEnabled = anySelected;
}
catch (Exception ex)
{
ErrorMessageBox.Show("recheck", ex, this);
}
}
Any ideas? Thanks in advance.
I found that the problem happened when you double click on the cell and it moved it to the cell editing template. In my case, I didn't have a cell editing template defined, so it used the same cell template, but instead of not changing anything, it apparently decided to make a new check box. I set the column's IsReadOnly property to true, and it fixed it. An alternate solution:
DataContext="{Binding}" (in XAML, or the code equivalent:)
cb.SetBinding(FrameworkElement.DataContextProperty, new Binding());
I'm not sure why this one fixes it, since I thought the default DataContext is {Binding}. Perhaps it's a Silverlight bug, and it gets set in a different order if you define it explicitly instead of leaving it the default.

Categories

Resources