Before I start explaining my issue, please note that my target framework is .NET 3.5.
I have a textbox whose text is bound to a viewmodel property. My requirement is that when user enters something(via keyboard as well as Mouse Paste) into the textbox, any junk characters inside it should be cleaned and the textbox should be updated with the replaced string[In the below example ‘s’ to be replaced with ‘h’].
XAMLCode:
<Style x:Key="longTextField" TargetType="{x:Type TextBoxBase}">
<Setter Property="SnapsToDevicePixels" Value="True"/>
<Setter Property="OverridesDefaultStyle" Value="True"/>
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="AcceptsReturn" Value="True"/>
<Setter Property="AllowDrop" Value="true"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBoxBase}">
<Border
Name="Border"
Padding="2"
Background="Transparent"
BorderBrush="LightGray"
BorderThickness="1">
<ScrollViewer Margin="0" x:Name="PART_ContentHost"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Foreground" Value="Black"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<TextBox Grid.Column="1" Grid.Row="2" Text="{Binding Value, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay, NotifyOnSourceUpdated=True, NotifyOnTargetUpdated=True}" MinLines="3" TextWrapping="Wrap"
SpellCheck.IsEnabled="True" Style="{StaticResource longTextField}"></TextBox>
ViewModel property:
private string _value;
public string Value
{
get
{
return _value;
}
set
{
if (_value == value)
return;
_value = value;
//replaces 's' with 'h' and should update the textbox.
_value = _value.Replace('s','h');
RaisePropertyChanged(() => Value);
}
}
The above is simply not working for me. The view model property setter is firing…the value is getting replaced..however the textbox is not getting updated. What is confusing is that this works perfectly on .Net4.0.
Do you know why this wont work and what is a potential solution to this problem, of course other than upgrading to .NET 4.0?
My requirement:
-
User can type as well as paste anything into a multilined textbox.
-
The text can contain junk which should be changed before it comes on to the textbox.
Thanks in advance,
-Mike
I encountered a very similar problem where I wanted the two way binding and I was modifying the value in the ViewModel and expecting to see the update in the TextBox. I was able to get it resolved. Although I was using .NET 4.0, I basically had the same issue, so this may be worth trying out for your situation with 3.5 as well.
Short Answer:
What I encountered was a bug where the
TextBox'sdisplayed text was getting out of sync with the value of thatTextBox'sownTextproperty. Meleak’s answer to a similar question clued me in to this and I was able to verify this with the debugger in Visual Studio 2010, as well as by employing Meleak’sTextBlocktechnique.I was able to resolve it by using explicit binding. This required handling the
UpdateSource()andUpdateTarget()issues myself in code behind (or in a custom control code as I eventually did to make it easier to reuse).Further Explanation:
Here’s how I handled the explicit binding tasks. First, I had an event handler for the TextChanged event which updated the source of the binding:
Second, in I had an event handler for the TextBox’s Loaded event. In that handler, I registered a handler for the PropertyChanged event of my ViewModel (the ViewModel was the “DataContext” here):
Finally, in the PropertyChanged handler, I cause the TextBox to grab the value from the ViewModel (by initiating the UpdateTarget()). This makes the TextBox get the modified string from the ViewModel (in your case the one with replaced characters). In my case I also had to handle restoring the user’s caret position after refreshing the text (from the UpdateTarget()). That part may or may not apply to your situation though.