Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
ValueConverter behaviour
Message
From
18/07/2011 13:12:19
 
 
General information
Forum:
ASP.NET
Category:
Windows Presentation Foundation (WPF)
Environment versions
Environment:
C# 4.0
Miscellaneous
Thread ID:
01518156
Message ID:
01518455
Views:
49
>>>>>>>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.
>
>I'd forgotten about this: http://msdn.microsoft.com/en-us/library/system.diagnostics.presentationtracesources.tracelevel.aspx
>Useful for getting a better insight into what's going on (especially if validation/exception handling are introduced)......

Ya, that's a good one, this is the post I refer to when I need to debug a binding:

http://bea.stollnitz.com/blog/?p=52
Previous
Reply
Map
View

Click here to load this message in the networking platform