wpf - two - Cómo configurar y obtener actualizaciones fuente de un cuadro de texto en codebehind?
wpf converter (3)
Solo una breve pregunta:
En wpf, ¿cómo configuro y obtengo actualizaciones de fuente de un cuadro de texto en código subyacente?
Gracias
Actualización:
Sigo el código de AngleWPF:
var bndExp = BindingOperations.GetBindingExpression(this, TextBox.TextProperty);
var myBinding
= bndExp.ParentBinding;
var updateSourceTrigger = myBinding.UpdateSourceTrigger;
Pero tengo la excepción:
Se produjo una excepción no controlada del tipo ''System.Reflection.TargetInvocationException'' en PresentationFramework.dll. Información adicional: el destinatario de una invocación ha lanzado una excepción.
¿Qué quieres decir con UpdateSourceTrigger
de TextBox
? ¿ UpdateSourceTrigger
decir UpdateSourceTrigger
de TextBox.TextProperty
''s Binding
?
Por ejemplo, si tiene un TextBox
llamado myTextBox
tiene su propiedad Text
vinculada a alguna fuente, entonces puede obtener fácilmente su objeto UpdateSourceTrigger
y Binding
través de la llamada GetBindingExpression()
.
var bndExp
= BindingOperations.GetBindingExpression(myTextBox, TextBox.Textproperty);
var myBinding
= bndExp.ParentBinding;
var updateSourceTrigger
= myBinding.UpdateSourceTrigger;
Pero es complicado configurar UpdateSourceTrigger
para un enlace ya usado. Por ejemplo, en el caso anterior, no podrá establecer myBinding.UpdateSourceTrigger
en otra cosa. Esto no está permitido cuando un objeto vinculante ya está en uso.
Es posible que tenga que clonar profundamente el objeto vinculante y establecer un nuevo UpdateSourceTrigger
y asignarlo de nuevo al TextBox
. La clonación no existe para la clase de Binding
. Puede que tenga que escribir su propio código de clonación para el mismo.
var newBinding = Clone(myBinding); //// <--- You may have to code this function.
newBinding.UpdateSourceTrigger = UpdateSourceTrigger.Explicit;
myTextBox.SetBinding(TextBox.TextProperty, newBinding);
Alternativamente, también puede tratar de desconectar el Enlace existente y actualizarlo y asignarlo de nuevo ...
myTextBox.SetBinding(TextBox.TextProperty, null);
myBinding.UpdateSourceTrigger = UpdateSourceTrigger.Explicit;
myTextBox.SetBinding(TextBox.TextProperty, myBinding);
Avíseme si alguno de estos consejos ayuda.
Otra forma de implementarlo es establecer el enlace en el controlador de eventos cargado en TextBox. Debajo está el xaml de TextBox:
<TextBox Grid.Row="0"
x:Name="txtName"
Text="{Binding Name}"
Loaded="TxtName_OnLoaded" />
Ahora, en código subyacente para TxtName_OnLoaded, eventhandler creará un nuevo objeto de enlace y lo inicializará según nuestras necesidades. También agregaremos ValidationRule en él.
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);
}
Como puede ver en la implementación anterior, hemos creado un objeto de enlace con una nueva ruta de enlace. También se le asignó UpdateSourceTrigger al objeto Binding recién creado.
Un enlace puede tener múltiples reglas de validación. Agregaremos una regla de validación en ella. Ahora podemos establecer el enlace a TextProperty del cuadro de texto.
Beneficios: Puede vincular múltiples objetos de dependencia a las propiedades del objeto Regla de validación desde el código detrás del cual no es posible con xaml. Por ejemplo:
Lo usé para validar las entradas en el evento TextChanged, donde comparo la entrada con la lista de elementos almacenados como propiedad pública ObservableCollection, enlazada con Grid, en ApplicationViewModel. Code of ValidationRule es el siguiente:
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);
}
}
El código anterior toma entrada y verifica la disponibilidad en la colección observable "Entradas". La regla da falso ValidationResult si el valor existe. A través de esta implementación, verifico la unicidad de las entradas en el tiempo de ejecución.
Espero que lo hayan disfrutado.
Creo que esta es la forma correcta de hacer esto:
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);