WPF TwoWay Bind to Current Source with Converter?

Is there a problem with data binding in WPF when binding to the current source (Path = ".") And using a converter? Bidirectional binding doesn't seem to work in this situation.

I know I can change the path, but I want to pass the "Name" value to the converter.

I cannot get the following example:

<Window x:Class="WpfTest.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:l="clr-namespace:WpfTest"
Title="Window1" Height="600" Width="600">

<Window.Resources>
    <l:Person x:Key="myDataSource" Name="Cam"/>

    <l:TestConverter x:Key="converter" />
</Window.Resources>

<StackPanel>
    <StackPanel.DataContext>
        <Binding Source="{StaticResource myDataSource}"/>
    </StackPanel.DataContext>

    <TextBox>
        <TextBox.Text>
            <Binding 
                Path="." 
                UpdateSourceTrigger="PropertyChanged"  
                Converter="{StaticResource converter}" 
                ConverterParameter="Name" 
                />
        </TextBox.Text>
    </TextBox> 
    <TextBlock Text="{Binding Path=Name}"/>
</StackPanel>
</Window>

class TestConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return Reverse(value, parameter);
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return Reverse(value, parameter);
    }

    private static object Reverse(object value, object parameter)
    {
        if (value == null)
            throw new ArgumentNullException("value", "value is null.");
        if (parameter == null)
            throw new ArgumentNullException("parameter", "parameter is null.");

        Person p = (Person)value;

        if (parameter.ToString() == "Name")
        {
            StringBuilder sb = new StringBuilder();
            for (int i = p.Name.Length - 1; i >= 0; i--)
            {
                sb.Append(p.Name[i]);
            }

            return sb.ToString();
        }

        throw new NotImplementedException();
    }
}

public class Person:INotifyPropertyChanged
{
    private string name;
    public string Name
    {
        get
        {
            return name;
        }
        set
        {
            name = value;

            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs("Name"));
        }
    }
    public event PropertyChangedEventHandler PropertyChanged;
}

      

+1


source to share


2 answers


Cameron,

I'm not sure about this what you are trying to do.

You attach to "." which means you should be able to convert from String to Person and Person to String, but your implementation doesn't. But then you would change the instance pointed to by the myDataSource resource. I'm not sure if you can do this.



If you just want to change the string, why not specify Binding.Path as "Name" and provide a converter that does what you want for the string?

Sam

+1


source


You cannot use bi-directional binding to the current source (with or without converters).

Think about it without converters for a minute, when binding to the current source you have no property to set - other than the DataContext itself, which is often inferred from another source (for example, it can be set to a list item using ItemControl), so there is no point in overriding property DataContext.



Therefore WPF will not try to link the changes back to source because it cannot change the source.

Now a custom ValueConverter can obviously do something, including things that are not just conventions but useful in your particular situation, but a value converter just has to convert the value type - and the system has nothing to do with the result of the value converter in that in case it has nowhere to assign it - so it makes no sense to call a value converter.

+1


source







All Articles