Двухсторонняя привязка данных WPF к Textbox.Text работает только в одном направлении - PullRequest
0 голосов
/ 20 сентября 2019

Мой вопрос не о сериализации. Я заставляю сериализованную часть работать нормально, но для контекста я пытаюсь сериализовать некоторые свойства, заданные пользователем в форме WPF, и поэтому требую двустороннюю привязку (которую яможет работать только в одном направлении: обновления от цели к источнику).

Допустим, я определил свойство приложения, которое является контейнером для моих свойств. Я хочу быть сериализуемым:

public SerializableApplicationProperties ThisAppsSerializableProperties { get; set; }

Класс SerializableApplicationProperties выглядит следующим образом:

[Serializable]
public class SerializableApplicationProperties
{

    public SerializableApplicationProperties()
    {
        UserSelectedPreFillFilePath = new ObservableString();
    }

    public SerializableApplicationProperties(string defaultFilePath)
    {
        UserSelectedPreFillFilePath = new ObservableString(defaultFilePath);
    }

    public ObservableString UserSelectedPreFillFilePath { get; set; }

}

У меня есть одно свойство, определенное до сих пор, что мне нужно установить двухстороннее связывание для в коде (да, в коде).Пожалуйста, не предлагайте, как я могу сделать это в разметке XAML, если только вы не объясните, как сделать это полностью в коде.

Свойство - "UserSelectedPreFillFilePath", которое, как вы видите, имеет тип "ObservableString".

Класс ObservableString выглядит следующим образом:

 [Serializable]
    public class ObservableString : INotifyPropertyChanged
    {

        private string _stringValue;
        public string StringValue
        {
            get { return _stringValue; }
            set
            {
                _stringValue = value;
                OnPropertyChanged("StringValue");
            }
        }

        public ObservableString() { }

        public ObservableString(string value)
        {
            this._stringValue = value;
        }

        protected void OnPropertyChanged(string name)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(name));
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

    }

Очень простой класс, который содержит свойство "StringValue" и реализует INotifyChange.

Итак, я пытаюсь установить двадвусторонняя привязка между этим «UserSelectedPreFillFileLocation» и текстовым полем в главном окне.

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

Затем, когда приложение загружается из файла (десериализуется), это текстовое поле автоматически заполняется значением UserSelectedPreFillFileLocation через привязку.

Второе, мое определение класса конвертера:

[ValueConversion(typeof(ObservableString), typeof(string))]
class ObservableStringToStringConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        ObservableString myVar = (ObservableString)value;
        return myVar.StringValue;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        string myVar = (string)value;
        return new ObservableString(myVar);
    }
}

Наконец, вот определение связывания.Привязка работает от цели к источнику, но не наоборот.IE, когда пользователь обновляет текстовое поле, обновляется UserSelectedPreFillFileLocation, но не наоборот.

        Binding UserSelectedPreFillFilePathBinding = new Binding();
        UserSelectedPreFillFilePathBinding.Path = new PropertyPath(nameof(ThisAppsSerializableProperties.UserSelectedPreFillFilePath));
        UserSelectedPreFillFilePathBinding.Source = ThisAppsSerializableProperties;          
        UserSelectedPreFillFilePathBinding.Converter = new ObservableStringToStringConverter();
        UserSelectedPreFillFilePathBinding.Mode = BindingMode.TwoWay;
        UserSelectedPreFillFilePathBinding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
        ThisAppInstanceMainWindow.TxtbxPrefillFileLocation.SetBinding(TextBox.TextProperty, UserSelectedPreFillFilePathBinding);

1 Ответ

0 голосов
/ 20 сентября 2019

Я обнаружил, что я делаю неправильно.

Я действительно определил ObservableString, и свойство наблюдаемого, которое вызывает событие измененного свойства, является StringValue внутри класса.

Итак, в этомВ этом случае мне даже не понадобился конвертер, поскольку исходное свойство, которое я должен был определить для привязки, было StringValue, а исходным объектом должен был быть UserSelectedPreFillFilePath.

Исправленный код, который теперь отлично работает с двумяспособ связывания:

        Binding UserSelectedPreFillFilePathBinding = new Binding();
        UserSelectedPreFillFilePathBinding.Path = new PropertyPath(nameof(ThisAppsSerializableProperties.UserSelectedPreFillFilePath.StringValue));
        UserSelectedPreFillFilePathBinding.Source = ThisAppsSerializableProperties.UserSelectedPreFillFilePath;
        UserSelectedPreFillFilePathBinding.Mode = BindingMode.TwoWay;
        UserSelectedPreFillFilePathBinding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
        ThisAppInstanceMainWindow.TxtbxPrefillFileLocation.SetBinding(TextBox.TextProperty, UserSelectedPreFillFilePathBinding);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...