Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
ValueConverter behaviour
Message
From
18/07/2011 04:02:39
 
 
To
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:
01518415
Views:
36
>>>>>>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)......
Previous
Next
Reply
Map
View

Click here to load this message in the networking platform