Как установить и получить updateourcetrigger из текстового поля в codebehind?
Просто короткий вопрос:
В wpf, как мне установить и получить updatesourcetrigger текстового поля в codebehind?
Спасибо
Обновить:
Я следую за кодом AngleWPF:
var bndExp = BindingOperations.GetBindingExpression(this, TextBox.TextProperty);
var myBinding
= bndExp.ParentBinding;
var updateSourceTrigger = myBinding.UpdateSourceTrigger;
Но я получил исключение:
Произошло необработанное исключение типа "System.Reflection.TargetInvocationException" в PresentationFramework.dll Дополнительная информация: Исключение было сгенерировано целью вызова.
3 ответа
Что вы подразумеваете под UpdateSourceTrigger
из TextBox
? Вы хотите сказать UpdateSourceTrigger
из TextBox.TextProperty
"s Binding
?
Например, если у вас есть TextBox
названный myTextBox
имея его Text
свойство связано с каким-то источником, то вы можете легко получить это UpdateSourceTrigger
а также Binding
объект через GetBindingExpression()
вызов.
var bndExp
= BindingOperations.GetBindingExpression(myTextBox, TextBox.Textproperty);
var myBinding
= bndExp.ParentBinding;
var updateSourceTrigger
= myBinding.UpdateSourceTrigger;
Но это сложно установить UpdateSourceTrigger
для уже использованной привязки. Например, в приведенном выше случае вы не сможете установить myBinding.UpdateSourceTrigger
к чему-то еще. Это не допускается, когда объект привязки уже используется.
Возможно, вам придется глубоко клонировать объект привязки и установить новый UpdateSourceTrigger
к нему и назначить его обратно TextBox
, Клонирование не существует для Binding
учебный класс. Возможно, вам придется написать свой собственный код клонирования для того же.
var newBinding = Clone(myBinding); //// <--- You may have to code this function.
newBinding.UpdateSourceTrigger = UpdateSourceTrigger.Explicit;
myTextBox.SetBinding(TextBox.TextProperty, newBinding);
Кроме того, вы также можете попытаться отсоединить существующий Binding, обновить его и назначить обратно...
myTextBox.SetBinding(TextBox.TextProperty, null);
myBinding.UpdateSourceTrigger = UpdateSourceTrigger.Explicit;
myTextBox.SetBinding(TextBox.TextProperty, myBinding);
Дайте мне знать, если какой-либо из этих советов поможет.
Еще один способ реализовать это - установка привязки в обработчике событий, загруженном в TextBox. Ниже приведен xaml TextBox:
<TextBox Grid.Row="0"
x:Name="txtName"
Text="{Binding Name}"
Loaded="TxtName_OnLoaded" />
Теперь в коде для TxtName_OnLoaded обработчик событий создаст новый объект Binding и инициализирует его в соответствии с нашими потребностями. Также мы добавим ValidationRule в него.
private void TxtName_OnLoaded(object sender, RoutedEventArgs e)
{
ApplicationViewModel appVm = this.DataContext as ApplicationViewModel;
TextBox TxtName = sender as TextBox;
if (TxtName == null)
return;
Binding newBinding = new Binding("Name");
newBinding.ValidatesOnDataErrors = true;
newBinding.ValidatesOnExceptions = true;
newBinding.NotifyOnValidationError = true;
newBinding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
validator.ErrorMessage = "Labware name should be unique.";
validator.ApplicationViewModel = appVm;
if (!newBinding.ValidationRules.Contains(validator))
newBinding.ValidationRules.Add(validator);
TxtName.SetBinding(TextBox.TextProperty, newBinding);
}
Как вы можете видеть в приведенной выше реализации, мы создали объект Binding с новым путем привязки. Также назначен UpdateSourceTrigger для вновь созданного объекта Binding.
Привязка может иметь несколько правил проверки. Мы добавим в него правило проверки. Теперь мы можем установить привязку к TextProperty текстового поля.
Преимущества: Вы можете привязать несколько объектов зависимостей к свойствам объекта правила валидации из кода, который недоступен в xaml. Например:
Я использовал его для проверки входных данных в событии TextChanged, где я сравниваю входные данные со списком элементов, хранящихся в виде открытого свойства ObservableCollection, связанного с сеткой, в ApplicationViewModel. Код ValidationRule выглядит следующим образом:
public class UniqueValueValidator : ValidationRule
{
public string ErrorMessage { get; set; }
public ApplicationViewModel ApplicationViewModel { get; set; }
public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)
{
if (value == null)
return null;
var lws = ApplicationViewModel.Inputs.Where(s => s.Name.Equals(value.ToString())).FirstOrDefault();
if (lws != null)
return new ValidationResult(false, ErrorMessage);
return new ValidationResult(true, null);
}
}
Выше код принимает входные данные и проверяет доступность в наблюдаемой коллекции "Входы". Правило дает ложь ValidationResult, если значение существует. Благодаря этой реализации я проверяю уникальность входных данных во время выполнения.
Надеюсь, вам, ребята, понравилось.
Я думаю, что это правильный способ сделать это:
Binding binding = new Binding();
binding.Source = new CustomerViewModel();;
binding.Path = new PropertyPath("Customer.Name");
binding.Mode = BindingMode.TwoWay;
binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
txtCustName.SetBinding(TextBox.TextProperty, binding);