Я испытываю затруднения при привязке данных a TextBox.Text
свойство к методу объекта. Идея позволяет пользователю писать в a TextBox
имя файла и затем имеет a TextBlock
вывод, что расширение файла.
class GetFileInfo
{
public string GetFileExtension(string fileName)
{
return Path.GetExtension(fileName);
}
}
Вот мой XAML:
abc.text
По некоторым причинам это ничего не делает. Anyknow мог указать на то, что может быть причинами? Вот то, что я вижу на разработчике и когда я запускаю приложение:
И вот то, что происходит, когда я пытаюсь установить другой текст во времени выполнения:
Вот ошибка, данная 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 (Объектное значение)'
Хорошо, похоже, это ошибка при запуске WPF 4.0. , как можно увидеть в комментариях здесь .
Ой, я немного поторопился ... пример работает отлично, пока вы скомпилируете его для фреймворка 3.5 (в VS 2010). Но если вы конвертируете его в WPF 4.0, то проецируйте метод WeightOnPlanet на ObjectDataProvider больше не вызывается в odp2, когда вы редактируете текстовое поле. Я попытался найти какие-либо новые атрибуты либо в Binding, либо в ObjectDataProvider - но пока ничего не вышло…
При компиляции в 3.5 это работает здесь хорошо.
Похоже, вам нужно получить представление о MVVM, посмотрите эту классическую статью. http://msdn.microsoft.com/en-us/magazine/dd419663.aspx
Хотя можно использовать Binding
для вызова метода и получения его возвращаемого значения, это непросто. Гораздо проще привязать к свойствам и использовать комбинацию привязки и уведомления об изменении для получения желаемого результата.
Создайте класс с двумя свойствами: Имя файла
и Расширение
. Имя файла
- это просто свойство строки для чтения / записи. Расширение
- это строковое свойство только для чтения, геттер которого вызывает метод, который вы пытаетесь вызвать.
Теперь сделайте этот класс реализацией INotifyPropertyChanged
, потому что, если свойство может измениться в коде, ему нужен способ сообщить привязке, что это было сделано. Сделайте так, чтобы установщик свойства Имя файла
уведомлял привязки об изменении свойства Расширение
.
Добавьте привязку
к TextBox
, которая привязывается к свойству Filename
, используя режим TwoWay
. Добавьте привязку
к TextBox
, которая привязывается к Extension
, используя режим по умолчанию OneWay
.
Последовательность событий такова:
имя файла
в связанное текстовое поле
и нажимает клавишу TAB.
теряет фокус. Binding
- это TwoWay
, и он использует поведение по умолчанию - обновление источника, когда цель теряет фокус, вот что он делает.
обновляет источник, вызывая метод установки Имя файла
. имени файла
вызывает PropertyChanged
.
обрабатывает PropertyChanged
, просматривает свой аргумент и видит, что свойство Расширение
изменилось.
вызывает геттер свойства Extension
. Extension
вызывает метод для определения расширения для Filename
и возвращает его в привязку Binding
.
обновляет свое целевое TextBox
с новым значением Extension
. Это основная концепция, лежащая в основе привязки данных и шаблона MVVM.Как только вы это поймете, это станет вашей второй натурой, и разработка WPF станет примерно в десять миллионов раз проще.
Привязка данных требует, чтобы событие 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 ));
}
}
Установлен ли DataContext
? В коде программной части вы установили для своего TextBlock
значение «saadsas» (я могу только догадываться), что нарушило привязку данных?