WPF TwoWay Привязать к источнику тока с помощью конвертера? - PullRequest
1 голос
/ 17 ноября 2008

Есть ли проблема с привязкой данных в WPF при привязке к текущему источнику (Path = ".") И использовании конвертера? Двухстороннее связывание в этой ситуации не работает.

Я знаю, что могу изменить путь, но я хочу иметь возможность передать значение "Имя" в преобразователь.

Я не могу заставить работать следующий пример:

<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;
}

Ответы [ 2 ]

1 голос
/ 18 ноября 2008

Нельзя использовать двустороннюю привязку с текущим источником (с преобразователями или без них).

Подумайте об этом без конвертеров на минуту, когда при привязке к текущему источнику у вас нет свойства для установки - кроме самого DataContext, который часто является производным от другого источника (например, он может быть установлен в элемент списка элементом ItemControl), поэтому нет смысла переопределять свойство DataContext.

Таким образом, WPF не будет пытаться привязать изменения к источнику, поскольку он не может изменить источник.

Теперь пользовательский ValueConverter, очевидно, может делать что угодно, включая вещи, которые не являются просто соглашениями о значениях, но полезны в вашей конкретной ситуации, но преобразователь значений просто должен преобразовывать тип значения - и система не имеет ничего общего с результат преобразователя значений в этом случае, ему некуда его присвоить - поэтому нет смысла вызывать преобразователь значений.

1 голос
/ 17 ноября 2008

Cameron

Я не совсем уверен из того, что вы пытаетесь сделать.

Вы связываете с "." Это означает, что вам нужно иметь возможность преобразовывать строку в Person и Person в строку, но ваша реализация этого не делает. Но тогда вы бы изменили экземпляр, на который указывает myDataSource ресурса. Я не уверен, что вы можете сделать это.

Если вы просто хотите изменить строку, почему бы вам не указать Binding.Path как «Имя» и предоставить преобразователь, который сделал то, что вы хотите для строки?

Sam

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...