two - ¿Solución para UpdateSourceTrigger LostFocus en Silverlight Datagrid?
wpf binding textbox (4)
Sé que son viejas noticias ... pero supe que esto era hacer esto:
Text = "{Ruta de enlace = newQuantity, UpdateSourceTrigger = PropertyChanged}"
Tengo una aplicación Silverlight 2 que valida los datos OnTabSelectionChanged. Inmediatamente comencé a desear que UpdateSourceTrigger permitiera algo más que LostFocus porque si hace clic en la pestaña sin quitar el control de un control, el objeto LINQ no se actualiza antes de la validación.
He solucionado el problema de los cuadros de texto al establecer el foco en otro control y luego volver a OnTextChanged:
Private Sub OnTextChanged(ByVal sender As Object, ByVal e As TextChangedEventArgs)
txtSetFocus.Focus()
sender.Focus()
End Sub
Ahora estoy tratando de lograr el mismo tipo de pirateo dentro de un DataGrid. My DataGrid usa DataTemplates generadas en tiempo de ejecución para CellTemplate y CellEditingTemplate. Traté de escribir el TextChanged = "OnTextChanged" en el TextBox en el DataTemplate, pero no se desencadena.
¿Alguien tiene alguna idea?
Esta publicación de blog muestra cómo actualizar el origen de un cuadro de texto de forma explícita utilizando la propiedad adjunta: http://www.thomasclaudiushuber.com/blog/2009/07/17/here-it-is-the-updatesourcetrigger-for-propertychanged-in -silverlight /
Podrías modificarlo fácilmente para que funcione con otros controles también ...
Me encontré con este mismo problema usando MVVM y Silverlight 4. El problema es que el enlace no actualiza la fuente hasta después de que el cuadro de texto pierde el foco, pero establecer el foco en otro control no funciona.
Encontré una solución usando una combinación de dos publicaciones de blog diferentes. Utilicé el código del concepto DefaultButtonHub de Patrick Cauldwell, con una "SmallWorkaround" de SmallWorkarounds.net
http://www.cauldwell.net/patrick/blog/DefaultButtonSemanticsInSilverlightRevisited.aspx
www.smallworkarounds.net/2010/02/elementbindingbinding-modes.html
Mi cambio dio como resultado el siguiente código para la clase DefaultButtonHub:
public class DefaultButtonHub
{
ButtonAutomationPeer peer = null;
private void Attach(DependencyObject source)
{
if (source is Button)
{
peer = new ButtonAutomationPeer(source as Button);
}
else if (source is TextBox)
{
TextBox tb = source as TextBox;
tb.KeyUp += OnKeyUp;
}
else if (source is PasswordBox)
{
PasswordBox pb = source as PasswordBox;
pb.KeyUp += OnKeyUp;
}
}
private void OnKeyUp(object sender, KeyEventArgs arg)
{
if (arg.Key == Key.Enter)
if (peer != null)
{
if (sender is TextBox)
{
TextBox t = (TextBox)sender;
BindingExpression expression = t.GetBindingExpression(TextBox.TextProperty);
expression.UpdateSource();
}
((IInvokeProvider)peer).Invoke();
}
}
public static DefaultButtonHub GetDefaultHub(DependencyObject obj)
{
return (DefaultButtonHub)obj.GetValue(DefaultHubProperty);
}
public static void SetDefaultHub(DependencyObject obj, DefaultButtonHub value)
{
obj.SetValue(DefaultHubProperty, value);
}
// Using a DependencyProperty as the backing store for DefaultHub. This enables animation, styling, binding, etc...
public static readonly DependencyProperty DefaultHubProperty =
DependencyProperty.RegisterAttached("DefaultHub", typeof(DefaultButtonHub), typeof(DefaultButtonHub), new PropertyMetadata(OnHubAttach));
private static void OnHubAttach(DependencyObject source, DependencyPropertyChangedEventArgs prop)
{
DefaultButtonHub hub = prop.NewValue as DefaultButtonHub;
hub.Attach(source);
}
}
Esto debería incluirse en algún tipo de documentación para Silverlight :)
Puedes hacerlo con un comportamiento aplicado al cuadro de texto también
// xmlns:int is System.Windows.Interactivity from System.Windows.Interactivity.DLL)
// xmlns:behavior is your namespace for the class below
<TextBox Text="{Binding Description,Mode=TwoWay,UpdateSourceTrigger=Explicit}">
<int:Interaction.Behaviors>
<behavior:TextBoxUpdatesTextBindingOnPropertyChanged />
</int:Interaction.Behaviors>
</TextBox>
public class TextBoxUpdatesTextBindingOnPropertyChanged : Behavior<TextBox>
{
protected override void OnAttached()
{
base.OnAttached();
AssociatedObject.TextChanged += new TextChangedEventHandler(TextBox_TextChanged);
}
protected override void OnDetaching()
{
base.OnDetaching();
AssociatedObject.TextChanged -= TextBox_TextChanged;
}
void TextBox_TextChanged(object sender, TextChangedEventArgs e)
{
var bindingExpression = AssociatedObject.GetBindingExpression(TextBox.TextProperty);
bindingExpression.UpdateSource();
}
}