I have a simple control that has a masked text box:
xmlns:extToolkit="http://schemas.microsoft.com/winfx/2006/xaml/presentation/toolkit/extended"
...
<extToolkit:MaskedTextBox Mask="000-000-000" Text="{Binding SerialNumber, UpdateSourceTrigger=PropertyChanged}" />
I also have a key binding on the control:
<UserControl.InputBindings>
<KeyBinding Command="{Binding SearchCommand}" Gesture="Enter" />
</UserControl.InputBindings>
The problem is when SearchCommand is executed I need the value they entered in the masked text box as the criteria for the search. With a regular text box this is no problem but apparently the MaskedTextBox control doesn't play well with PropertyChanged UpdateSourceTrigger.
If I click someplace else (so it looses focus) and then press enter it works, but obviously I don't want to have to do that. Are there any good workarounds for this situation?
You must bind your property to the Value property not the Text.
http://wpftoolkit.codeplex.com/wikipage?title=MaskedTextBox&referringTitle=Documentation
Related
I am using MVVM. I have a DataGrid which lists some airports. Now I have a textbox let the user to input some keywords to search for a particular airport so that the airport list will only display matched airports.
private string airport;
public string Airport
{
get { return airport; }
//the following will not be executed unless the cursor is removed from the textbox
set
{
airport = value;
//OnPropertyChanged("Airport");
}
}
view:
<TextBox x:Name="textBox_Airport" Text="{Binding Airport}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="TextChanged">
<i:InvokeCommandAction Command="{Binding Command_Airport}"></i:InvokeCommandAction>
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBox>
The problem is that the value of "Airport" will not be transmitted from UI to Property unless the focus is removed from the textbox, hence it leads to a null value exception in the command. I think to use a button for search instead of using "TextChanged" event could solve this but not user-friendly enough. How can I keep the "TextChanged" way and solve this using MVVM? Thanks.
Default mode of updating source for TextBox.Text property is LostFocus. Change it to PropertyChanged.
Text="{Binding Airport, UpdateSourceTrigger=PropertyChanged}"
And if you are working with .net 4.5 or newer, I suggest to use binding Delay as well. With Delay Airport property will be updated after user stopped typing, not on every key press. Search in this case can be triggered from Airport setter, which should allow user to type full search keyword, before actually searching it
Text="{Binding Airport, Delay=400, UpdateSourceTrigger=PropertyChanged}"
There are two TextBox on the WPF page. While user is typing into the first TextBox, the second TextBox must display modified text from the first TextBox. As a result both values must be binded to a view model.
Can it be done with Data Binding?
I was able to get the second TextBox display text from the first one implementing DependencyProperty on my view model. But I don't have the slightest idea how to apply transformation on the fly.
Maybe there is an easy way to achieve this?
Just use databinding with UpdateSourceTrigger set to PropertyChanged:
<TextBox x:Name='txt1' Text="{Binding MyText, UpdateSourceTrigger=PropertyChanged}" />
<TextBox x:Name='txt2' Text="{Binding MyText, UpdateSourceTrigger=PropertyChanged}" />
In this case it will update ViewModel's property on the fly instead of waiting for FocusLost.
Here is the sample XAML:
...
<ribbon:RibbonTab Header="MyTab">
<ribbon:RibbonGroup Header="Blah">
<ribbon:RibbonTextBox x:Name="MyTextBox"
IsEnabled="{Binding IsChecked, ElementName=MyCheckBox}" />
<ribbon:RibbonCheckBox x:Name="MyCheckBox" Label="some text" />
</ribbon:RibbonGroup>
</ribbon:RibbonTab>
...
For some reason, the text box stays disabled regardless of whether or not the check box is checked. Why is the binding not working properly?
You can add the above code minus the elipses at the top and bottom to a boiler plate WPF ribbon project and see if you can figure out what's wrong. I see no binding error diagnostics, for example.
Update: If a regular TextBox is substituted for the RibbonTextBox, the behavior becomes correct. I conclude that there must be some issue with binding the IsEnabled property of a RibbonTextBox.
Freaky update #2: Creating a basic RibbonTextBox and setting its IsEnabled property to True creates a disabled RibbonTextBox. What gives?
I have submitted a bug report on Microsoft Connect to further pursue this issue.
Final update: It's fixed in WPF 4.5.
As a wild guess, have you tried fully qualifying the property?
IsEnabled="{Binding RibbonCheckBox.IsChecked, ElementName=MyCheckBox}"
... or maybe even...
IsEnabled="{Binding CheckBox.IsChecked, ElementName=MyCheckBox}"
As the title states, I have a usercontrol with a textbox inside. The purpose of the user control is to add a spell check button and character count below the textbox. But for the most part, I'm using it just like a normal textbox:
<controls:SuperTextBox Text="{Binding Accomplishments, Mode=TwoWay, ValidatesOnNotifyDataErrors=True,NotifyOnValidationError=True}"
Height="200" EnableCharacterCounting="True" EnableSpellChecking="True" AcceptsReturn="True"
TextWrapping="Wrap" />
The problem I'm having is that I no longer get the nice red border when validation fails for the field. What do I need to do to reenable that behavior?
What you need to do here, it's to relay the validation of your UserControl back to the textbox.
I did answer a similar question here.
What exactly I want to do is that there are 2 tables,ie, user and userprofile and both of them have almost identical fields. I shall take example of the email field. There is a textbox and the User table email field value is displayed in it. What I want to do is, have a context menu such that when the user right clicks on the textbox, the menu displays both the User and UserProfile email field values. – developer 1 hour ago
Whatever value one selects from the context menu the textbox then displays that value. You can use Binding Email1 and Binding Email2, as I have no problems getting those two values from database so I shall change my code accordingly. As I am new to WPF and .NET framework itself, I am not sure how to achieve this. Please let me know if I have made myself clear this time.
I am not sure how to handle commands and events. Can anybody show me the code to accomalish this..
<TextBox Style="{StaticResource FieldStyle}" Text="{Binding Email1, UpdateSourceTrigger=PropertyChanged}">
<TextBox.BorderBrush>
<MultiBinding Converter="{StaticResource TextBoxBorderConverter}">
<Binding Path="Email1"/>
<Binding Path="Email2"/>
</MultiBinding>
</TextBox.BorderBrush>
</TextBox>
Thanks in advance
At risk of giving you a WPF/MVVM noob answer and getting flamed, here goes. I can't advise you on databinding with databases since I've never done it, so I will just give you the XAML and it's up to you to work on the database end.
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid>
<TextBox Height="28" Text={Binding PreferredEmail}">
<TextBox.ContextMenu>
<ContextMenu>
<MenuItem Header="{Binding Email1}" Command="{Binding Email1Command}" />
<MenuItem Header="{Binding Email2}" Command="{Binding Email2Command}" />
</ContextMenu>
</TextBox.ContextMenu>
</TextBox>
</Grid>
</Page>
In the databinding to objects case, PreferredEmail, Email1, and Email2 would bind to a dependency property or a property that raises the PropertyChanged event. This is how your ViewModel (or whatever you want to call the lower-level code) will update the data. If you change those values in code-behind, ultimately it'll get reflected in the context menu automagically. Then you have to implement two ICommand-based classes to handle the setting of PreferredEmail.
I think it's super lame to implement two command handlers, and it certainly won't scale well if you have to add more email sources. I think a better solution would be to use one command handler and a CommandParameter that is the selected MenuItem header, but I don't know how to do that. But in any case, the two command handler solution will still work if you're in a bind.