Привязка данных к методу в WPF

Я испытываю затруднения при привязке данных a TextBox.Text свойство к методу объекта. Идея позволяет пользователю писать в a TextBox имя файла и затем имеет a TextBlock вывод, что расширение файла.

class GetFileInfo
{
    public string GetFileExtension(string fileName)
    {
        return Path.GetExtension(fileName);
    }
}

Вот мой XAML:


    
        
            abc.text
        
    



    
        
            
        
    
    

По некоторым причинам это ничего не делает. Anyknow мог указать на то, что может быть причинами? Вот то, что я вижу на разработчике и когда я запускаю приложение:

alt text

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

alt text Вот ошибка, данная de отладчиком при попытке установить другой текст во времени выполнения:

Система. Windows. Ошибка данных: 8: не Может сохранить значение от цели назад к источнику. BindingExpression:Path=MethodParameters[0]; DataItem ='ObjectDataProvider' (HashCode=2207369); целевым элементом является 'Текстовое поле' (Имя ='textBox1'); целевое свойство является 'текстом' (введите 'Строку'), ArgumentException:'System. ArgumentException: Объект типа 'MS.Internal. Данные. PropertyPathWorker+IListIndexerArg' не может быть преобразован для ввода 'Системы. Int32'. в System. RuntimeType. TryChangeType (Объектное значение, редактор связей Редактора связей, культура CultureInfo, булевская переменная needsSpecialCast) в System. RuntimeType. CheckValue (Объектное значение, редактор связей Редактора связей, культура CultureInfo, BindingFlags invokeAttr) в System. Отражение. MethodBase. CheckArguments (Объект [] параметры, редактор связей Редактора связей, BindingFlags invokeAttr, культура CultureInfo, сигнал Подписи) в System. Отражение. RuntimeMethodInfo. Вызовите (Возразите obj, BindingFlags invokeAttr, редактору связей Редактора связей, Объект [] параметры, культура CultureInfo, булевская переменная skipVisibilityChecks) в System. Отражение. RuntimeMethodInfo. Вызовите (Возразите obj, BindingFlags invokeAttr, редактору связей Редактора связей, Объект [] параметры, культура CultureInfo) в System. Отражение. RuntimePropertyInfo. SetValue (Возражают obj, Объектному значению, BindingFlags invokeAttr, редактору связей Редактора связей, Объект [] индекс, культура CultureInfo) в MS.Internal. Данные. PropertyPathWorker. SetValue (Объектный объект, Объектное значение) в MS.Internal. Данные. ClrBindingWorker. UpdateValue (Объектное значение) в System. Windows. Данные. BindingExpression. UpdateSource (Объектное значение)'

13
задан Glorfindel 19 June 2019 в 13:07
поделиться

5 ответов

Хорошо, похоже, это ошибка при запуске WPF 4.0. , как можно увидеть в комментариях здесь .

Ой, я немного поторопился ... пример работает отлично, пока вы скомпилируете его для фреймворка 3.5 (в VS 2010). Но если вы конвертируете его в WPF 4.0, то проецируйте метод WeightOnPlanet на ObjectDataProvider больше не вызывается в odp2, когда вы редактируете текстовое поле. Я попытался найти какие-либо новые атрибуты либо в Binding, либо в ObjectDataProvider - но пока ничего не вышло…

При компиляции в 3.5 это работает здесь хорошо.

0
ответ дан 2 December 2019 в 01:21
поделиться

Похоже, вам нужно получить представление о MVVM, посмотрите эту классическую статью. http://msdn.microsoft.com/en-us/magazine/dd419663.aspx

2
ответ дан 2 December 2019 в 01:21
поделиться

Хотя можно использовать Binding для вызова метода и получения его возвращаемого значения, это непросто. Гораздо проще привязать к свойствам и использовать комбинацию привязки и уведомления об изменении для получения желаемого результата.

Создайте класс с двумя свойствами: Имя файла и Расширение . Имя файла - это просто свойство строки для чтения / записи. Расширение - это строковое свойство только для чтения, геттер которого вызывает метод, который вы пытаетесь вызвать.

Теперь сделайте этот класс реализацией INotifyPropertyChanged , потому что, если свойство может измениться в коде, ему нужен способ сообщить привязке, что это было сделано. Сделайте так, чтобы установщик свойства Имя файла уведомлял привязки об изменении свойства Расширение .

Добавьте привязку к TextBox , которая привязывается к свойству Filename , используя режим TwoWay . Добавьте привязку к TextBox , которая привязывается к Extension , используя режим по умолчанию OneWay .

Последовательность событий такова:

  1. Пользователь вводит новое имя файла в связанное текстовое поле и нажимает клавишу TAB.
  2. Текстовое поле теряет фокус.
  3. Поскольку режим Binding - это TwoWay , и он использует поведение по умолчанию - обновление источника, когда цель теряет фокус, вот что он делает.
  4. Привязка обновляет источник, вызывая метод установки Имя файла .
  5. Средство установки имени файла вызывает PropertyChanged .
  6. Привязка обрабатывает PropertyChanged , просматривает свой аргумент и видит, что свойство Расширение изменилось.
  7. Привязка вызывает геттер свойства Extension .
  8. Получатель свойства Extension вызывает метод для определения расширения для Filename и возвращает его в привязку Binding .
  9. Привязка обновляет свое целевое TextBox с новым значением Extension .

Это основная концепция, лежащая в основе привязки данных и шаблона MVVM.Как только вы это поймете, это станет вашей второй натурой, и разработка WPF станет примерно в десять миллионов раз проще.

7
ответ дан 2 December 2019 в 01:21
поделиться

Привязка данных требует, чтобы событие NotifyPropertyChanged было вызывается при обновлении источника. В этом случае вам нужно обернуть этот вызов функции в get / set следующим образом:



public class FileWrapper: System.ComponentModel.INotifyPropertyChanged{
    private string m_filename;

    public string FileExtension{
        get{ return GetFileExtension(FileName);}
    }

    public string FileName{
        get{ return m_filename;}
        set{ m_filename = value; OnPropertyChanged("FileName"); OnPropertyChanged( "FileExtension");
    }

    public string GetFileExtension( string filename){
        //implementation
    }

    public event System.ComponentModel.NotifyPropertyChangedEvent PropertyChanged = (a,b)=>{};

    protected void OnPropertyChanged(string property){
        PropertyChanged( this, new System.ComponentModel.PropertyChangedEventArgs( property ));
    }
}

1
ответ дан 2 December 2019 в 01:21
поделиться

Установлен ли DataContext ? В коде программной части вы установили для своего TextBlock значение «saadsas» (я могу только догадываться), что нарушило привязку данных?

0
ответ дан 2 December 2019 в 01:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: