Tengo una TextBox
y una Button
en mi opinión.
Ahora estoy verificando una condición al hacer clic en el botón y si la condición resulta ser falsa, mostrar el mensaje al usuario, y luego tengo que configurar el cursor para el TextBox
control.
if (companyref == null)
{
var cs = new Lipper.Nelson.AdminClient.Main.Views.ContactPanels.CompanyAssociation();
MessageBox.Show("Company does not exist.", "Error", MessageBoxButton.OK,
MessageBoxImage.Exclamation);
cs.txtCompanyID.Focusable = true;
System.Windows.Input.Keyboard.Focus(cs.txtCompanyID);
}
El código anterior está en ViewModel.
El CompanyAssociation
es el nombre de la vista.
Pero el cursor no se está configurando en el TextBox
.
El xaml es:
<igEditors:XamTextEditor Name="txtCompanyID"
KeyDown="xamTextEditorAllowOnlyNumeric_KeyDown"
ValueChanged="txtCompanyID_ValueChanged"
Text="{Binding Company.CompanyId,
Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged}"
Width="{Binding ActualWidth, ElementName=border}"
Grid.Column="1" Grid.Row="0"
VerticalAlignment="Top"
HorizontalAlignment="Stretch"
Margin="0,5,0,0"
IsEnabled="{Binding Path=IsEditable}"/>
<Button Template="{StaticResource buttonTemp1}"
Command="{Binding ContactCommand}"
CommandParameter="searchCompany"
Content="Search"
Width="80"
Grid.Row="0" Grid.Column="2"
VerticalAlignment="Top"
Margin="0"
HorizontalAlignment="Left"
IsEnabled="{Binding Path=IsEditable}"/>
Respuestas:
Déjame responder a tu pregunta en tres partes.
Me pregunto qué es "cs.txtCompanyID" en tu ejemplo. ¿Es un control TextBox? Si es así, entonces estás en el camino equivocado. En general, no es una buena idea tener ninguna referencia a la interfaz de usuario en su ViewModel. Puedes preguntar "¿Por qué?" pero esta es otra pregunta para publicar en Stackoverflow :).
La mejor manera de rastrear problemas con Focus es ... depurar el código fuente .Net. En serio. Me ahorró mucho tiempo muchas veces. Para habilitar la depuración del código fuente .net, consulte el blog de Shawn Bruke .
Finalmente, el enfoque general que utilizo para establecer el foco desde ViewModel es Propiedades adjuntas. Escribí una propiedad adjunta muy simple, que se puede configurar en cualquier UIElement. Y puede vincularse a la propiedad de ViewModel "IsFocused", por ejemplo. Aquí está:
Ahora en su Vista (en XAML) puede vincular esta propiedad a su Modelo de vista:
Espero que esto ayude :). Si no se refiere a la respuesta # 2.
Salud.
fuente
Keyboard.Focus(uie);
desde suOnIsFocusedPropertyChanged
evento si desea que su control reciba Keyboard Focus y Logical Focus...if ((bool)e.NewValue && uie.Dispatcher != null) { uie.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (Action)(() => uie.Focus())); // invoke behaves nicer, if e.g. you have some additional handler attached to 'GotFocus' of UIE. uie.SetValue(IsFocusedProperty, false); // reset bound value if possible, to allow setting again ...
veces incluso tengo que restablecer 'IsFocused' a falso en ViewModel, si quiero establecer el foco varias veces. Pero luego funciona, donde algunos otros métodos fallaron.public bool IsFocused { get { return _isFocused; } set { if (_isFocused == value) { _isFocused = false; OnPropertyChanged(); } _isFocused = value; OnPropertyChanged(); } }
Sé que esta pregunta ha sido respondida mil veces por ahora, pero hice algunas modificaciones a la contribución de Anvaka que creo que ayudarán a otros que tuvieron problemas similares.
En primer lugar, cambié la propiedad adjunta anterior de la siguiente manera:
Mi razón para agregar las referencias de visibilidad fueron las pestañas. Aparentemente, si usó la propiedad adjunta en cualquier otra pestaña fuera de la pestaña inicialmente visible, la propiedad adjunta no funcionó hasta que concentró manualmente el control.
El otro obstáculo fue crear una forma más elegante de restablecer la propiedad subyacente a falso cuando perdió el foco. Ahí es donde entraron los eventos de enfoque perdido.
Si hay una mejor manera de manejar el problema de visibilidad, avíseme.
Nota: Gracias a Apfelkuacha por la sugerencia de colocar BindsTwoWayByDefault en DependencyProperty. Lo había hecho hace mucho tiempo en mi propio código, pero nunca actualicé esta publicación. El Modo = TwoWay ya no es necesario en el código WPF debido a este cambio.
fuente
fe.Dispatcher.BeginInvoke(new Action(() => { fe.Focus(); }), DispatcherPriority.Loaded);
que se actualiza después de cargarse. Más información aquí: telerik.com/forums/isfocused-property#OXgFYZFOg0WZ2rxidln61QCreo que la mejor manera es mantener limpio el principio de MVVM, por lo que básicamente debe usar la clase Messenger provista con la luz MVVM y aquí está cómo usarla:
en su modelo de vista (exampleViewModel.cs): escriba lo siguiente
ahora en su View.cs (no el XAML el view.xaml.cs) escriba lo siguiente en el constructor
ese método funciona bien y con menos código y manteniendo los estándares MVVM
fuente
Ninguno de estos funcionó exactamente para mí, pero para el beneficio de otros, esto es lo que terminé escribiendo en base al código que ya se proporciona aquí.
El uso sería el siguiente:
Y la implementación sería la siguiente:
fuente
Este es un hilo viejo, pero no parece haber una respuesta con un código que aborde los problemas con la respuesta aceptada de Anavanka: no funciona si establece la propiedad en el modelo de vista en falso, o si establece su propiedad en cierto, el usuario hace clic manualmente en otra cosa y luego lo configura en verdadero nuevamente. Tampoco pude lograr que la solución de Zamotic funcionara de manera confiable en estos casos.
Reunir algunas de las discusiones anteriores me da el código a continuación que aborda estos problemas, creo:
Dicho esto, esto sigue siendo complejo para algo que se puede hacer en una línea en código subyacente, y CoerceValue no está destinado a ser utilizado de esta manera, por lo que tal vez el código subyacente sea el camino a seguir.
fuente
En mi caso, FocusExtension no funcionó hasta que cambié el método OnIsFocusedPropertyChanged. El original solo funcionaba en la depuración cuando un punto de interrupción detenía el proceso. En tiempo de ejecución, el proceso es demasiado rápido y no pasa nada. Con esta pequeña modificación y la ayuda de nuestro amigo Task, esto está funcionando bien en ambos escenarios.
fuente
El problema es que una vez que IsUserNameFocused se establece en verdadero, nunca será falso. Esto lo resuelve manejando GotFocus y LostFocus para FrameworkElement.
Estaba teniendo problemas con el formato del código fuente, así que aquí hay un enlace
fuente
El código brillante de Anvakas es para aplicaciones de escritorio de Windows. Si eres como yo y necesitas la misma solución para las aplicaciones de la Tienda Windows, este código puede ser útil:
fuente
Para aquellos que intentaban usar la solución de Anvaka anterior, tenía problemas con el enlace que solo funcionaba la primera vez, ya que lostfocus no actualizaría la propiedad a falso. Puede establecer manualmente la propiedad en falso y luego en verdadero cada vez, pero una mejor solución podría ser hacer algo como esto en su propiedad:
De esta manera, solo necesita establecerlo en verdadero, y se enfocará.
fuente
Utilizo WPF / Caliburn Micro y descubrí que "dfaivre" ha hecho una solución general y viable aquí: http://caliburnmicro.codeplex.com/discussions/222892
fuente
He encontrado solución editando el código según lo siguiente. No es necesario establecer primero la propiedad de enlace Falso y luego Verdadero.
fuente
Para Silverlight:
LoginViewModel.cs:
Login.xaml:
O
Para establecer el foco solo debes hacerlo en código:
Recuerde que este complemento es parte de una página html, por lo que otros controles en la página pueden tener el foco
fuente
Puede usar el patrón de diseño ViewCommand . Describe un método para el patrón de diseño MVVM para controlar una vista desde un modelo de vista con comandos.
Lo implementé en base a la sugerencia del Rey A.Majid de usar la clase MVVM Light Messenger. La clase ViewCommandManager maneja los comandos de invocación en vistas conectadas. Básicamente es la otra dirección de los Comandos regulares, en estos casos cuando un ViewModel necesita realizar alguna acción en su Vista. Utiliza la reflexión como comandos vinculados a datos y WeakReferences para evitar pérdidas de memoria.
http://dev.unclassified.de/source/viewcommand (también publicado en CodeProject)
fuente
Nadie parece haber incluido el paso final para facilitar la actualización de atributos a través de variables enlazadas. Esto es lo que se me ocurrió. Avíseme si hay una mejor manera de hacerlo.
XAML
ViewModel
fuente
En primer lugar, me gustaría agradecer a Avanka por ayudarme a resolver mi problema de enfoque. Sin embargo, hay un error en el código que publicó, es decir, en la línea: if (e.OldValue == null)
El problema que tuve fue que si primero haces clic en tu vista y enfocas el control, e.oldValue ya no es nulo. Luego, cuando configura la variable para enfocar el control por primera vez, esto da como resultado que no se configuren los controladores de enfoque perdido y enfocado. Mi solución a esto fue la siguiente:
fuente
Solo haz esto:
fuente
Después de implementar la respuesta aceptada, me encontré con un problema que al navegar por las vistas con Prism el TextBox todavía no se enfocaba. Un pequeño cambio en el controlador PropertyChanged lo resolvió
fuente
Un enfoque alternativo basado en @Sheridan responde aquí
En su modelo de vista, configure su enlace de la manera habitual y luego configure SomeTextIsFocused en true para establecer el foco en su cuadro de texto
fuente
La solución de Crucial para el problema de IsVisible me pareció muy útil. No resolvió completamente mi problema, pero sí lo hizo un código adicional que seguía el mismo patrón para el patrón IsEnabled.
Al método IsFocusedChanged agregué:
Y aquí está el controlador:
fuente
fuente
fuente