Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
ValueConverter behaviour
Message
From
17/07/2011 12:02:46
 
 
General information
Forum:
ASP.NET
Category:
Windows Presentation Foundation (WPF)
Environment versions
Environment:
C# 4.0
Miscellaneous
Thread ID:
01518156
Message ID:
01518397
Views:
43
>>>>>Example:
>>>>>The default UpdateSourceTrigger for a TextBox is LostFocus(). If I leave it that way and somewhere in code execute: TextBox.Text="Hello World" this is not relayed back to the source - until (and if) the TextBox subsequently loses focus.
>>>>>To updated the source immediately I need to set the UpdateSourceTrigger to PropertyChanged. If I do that then the source is also updated on every keystroke.
>>>>
>>>>Wouldn't TextBox.Text="Hello World" remove the binding on TextBox.Text and replace it with the string "Hello World"? Since the binding on TextBox.Text is now gone, the source would never be updated.
>>>>
>>>>Or am I still not following?
>>>
>>>Following completely - and I agree entirely that directly setting the Text property should replace the binding. The trouble is that is not what I'm seeing. It's been a long day and I may be missing something obvious but it you have time try this:
>>>Code:
using System;
>>>using System.ComponentModel;
>>>using System.Diagnostics;
>>>using System.Windows;
>>>using System.Windows.Data;
>>>
>>>namespace BindingTest
>>>{
>>>    public partial class MainWindow : Window, INotifyPropertyChanged
>>>    {
>>>        public MainWindow()
>>>        {
>>>            InitializeComponent();
>>>            DataContext = this;
>>>        }
>>>
>>>        string theText;
>>>        public string TheText
>>>        {
>>>            get { return theText; }
>>>            set
>>>            {
>>>                if (theText != value)
>>>                {
>>>                    theText = value;
>>>                    OnPropertyChanged("TheText");
>>>                }
>>>            }
>>>        }
>>>
>>>        public event PropertyChangedEventHandler PropertyChanged;
>>>
>>>        void OnPropertyChanged(string s)
>>>        {
>>>            if (PropertyChanged != null)
>>>                PropertyChanged(this, new PropertyChangedEventArgs(s));
>>>        }
>>>
>>>        private string s = "String A";
>>>        private void SetTarget(object sender, RoutedEventArgs e)
>>>        {
>>>            TB.Text = s;
>>>            s = s == "String A" ? "String B" : "String A";
>>>        }
>>>    }
>>>
>>>    public class TBConverter : IValueConverter
>>>    {
>>>        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
>>>        {
>>>            if (value == null) return Binding.DoNothing;
>>>            return ((string)value).ToUpper();
>>>        }
>>>
>>>        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
>>>        {
>>>            return ((String)value).ToLower();
>>>        }
>>>    }
>>>}
XAML:
<Window x:Class="BindingTest.MainWindow"
>>>        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
>>>        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
>>>        Title="MainWindow" Height="350" Width="525" 
>>>        xmlns:local="clr-namespace:BindingTest">
>>>    <Window.Resources>
>>>        <local:TBConverter x:Key="TBC" />
>>>    </Window.Resources>
>>>    <StackPanel>
>>>        <TextBox x:Name="TB" Height="31" HorizontalAlignment="Left" Margin="71,45,0,0"  VerticalAlignment="Top" Width="148"
>>>                 Text="{Binding Path=TheText,Mode=TwoWay, Converter={StaticResource TBC}}"/>
>>>        <TextBox x:Name="TB2" Height="31" HorizontalAlignment="Left" Margin="71,45,0,0"  VerticalAlignment="Top" Width="148"
>>>                 Text="{Binding Path=TheText,Mode=TwoWay, Converter={StaticResource TBC}}"/>
>>>        <Button Click="SetTarget">Set Target</Button>
>>>    </StackPanel>
>>></Window>
The binding and converter still appear to be operating after 'TB.Text = s;' (you need to set focus to the TextBox and tab out to get the source updated or, better, just set the UpdateSourceTrigger to PropertyChanged)
>>
>>Oh, wow, you're right, that does work. The binding doesn't get replaced when it's a TwoWay binding. It does break if it's OneWay. (Good to know)
>
>OneWayToSource doesn't break either. Of course, if it did, then it would be a pretty pointless option (s). In that light the behaviour when Mode is TwoWay makes sense.
>
>One other small discovery : If I set Mode to OneWayToSource with the above converter in place then the designer throws a NullReferenceException and refuses to display. The fix was to add a check for null in the ConvertBack() which was being called by the IDE

It makes some sense that it works that way. But since a custom control doesn't have control over the bindings, I can see some gotchas that could come out of this.
Previous
Next
Reply
Map
View

Click here to load this message in the networking platform