Esiste un modo MVVM per selezionare il testo in una casella di testo? Il framework MVVM che sto utilizzando è MVVM Light Toolkit di Laurent Bugnion.MVVM- Come posso selezionare il testo in una casella di testo?
risposta
Ogni volta che sto provando a influenzare direttamente la vista in un'applicazione MVVM "pura" (senza codice nella vista), userò Attached Properties per incapsulare qualsiasi effetto che sto cercando di ottenere. Creerò un'interfaccia che definisce le azioni che desidero intraprendere utilizzando eventi personalizzati. Quindi implemento questa interfaccia in ciascun ViewModel che eseguirà "questi" comandi sulla Vista. Infine, lego il mio ViewModel alla proprietà associata nella mia definizione di Vista. Il seguente codice mostra come questo per SelectAll e un TextBox. Questo codice può essere facilmente esteso per eseguire qualsiasi azione su qualsiasi componente nella vista.
mio Attached proprietà e l'interfaccia di definizione:
using System.Windows;
using System.Windows.Controls;
using System;
using System.Collections.Generic;
namespace SelectAllSample
{
public static class TextBoxAttach
{
public static readonly DependencyProperty TextBoxControllerProperty = DependencyProperty.RegisterAttached(
"TextBoxController", typeof(ITextBoxController), typeof(TextBoxAttach),
new FrameworkPropertyMetadata(null, OnTextBoxControllerChanged));
public static void SetTextBoxController(UIElement element, ITextBoxController value)
{
element.SetValue(TextBoxControllerProperty, value);
}
public static ITextBoxController GetTextBoxController(UIElement element)
{
return (ITextBoxController)element.GetValue(TextBoxControllerProperty);
}
private static readonly Dictionary<ITextBoxController, TextBox> elements = new Dictionary<ITextBoxController, TextBox>();
private static void OnTextBoxControllerChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var element = d as TextBox;
if (element == null)
throw new ArgumentNullException("d");
var oldController = e.OldValue as ITextBoxController;
if (oldController != null)
{
elements.Remove(oldController);
oldController.SelectAll -= SelectAll;
}
var newController = e.NewValue as ITextBoxController;
if (newController != null)
{
elements.Add(newController, element);
newController.SelectAll += SelectAll;
}
}
private static void SelectAll(ITextBoxController sender)
{
TextBox element;
if (!elements.TryGetValue(sender, out element))
throw new ArgumentException("sender");
element.Focus();
element.SelectAll();
}
}
public interface ITextBoxController
{
event SelectAllEventHandler SelectAll;
}
public delegate void SelectAllEventHandler(ITextBoxController sender);
}
La mia definizione ViewModel:
public class MyViewModel : ITextBoxController
{
public MyViewModel()
{
Value = "My Text";
SelectAllCommand = new RelayCommand(p =>
{
if (SelectAll != null)
SelectAll(this);
});
}
public string Value { get; set; }
public RelayCommand SelectAllCommand { get; private set; }
public event SelectAllEventHandler SelectAll;
}
mio Vista la definizione:
<Window x:Class="SelectAllSample.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:loc="clr-namespace:SelectAllSample"
Title="Window1" Height="150" Width="150">
<x:Code><![CDATA[
public Window1()
{
InitializeComponent();
DataContext = new MyViewModel();
}
]]></x:Code>
<StackPanel>
<TextBox Text="{Binding Value}" loc:TextBoxAttach.TextBoxController="{Binding}" />
<Button Content="Select All" Command="{Binding SelectAllCommand}" />
</StackPanel>
</Window>
Nota: Grazie a Josh Smith per RelayCommand (vedi codice in Figura 3 su this page). In questo esempio viene utilizzato in MyViewModel (e quasi tutto il mio codice MVVM).
trovare una buona introduzione alla proprietà associate qui: http://www.codeproject.com/KB/WPF/AttachedBehaviors.aspx
Grazie mille! – Justin
Ricevo un errore: "Delegate 'System.Action' non accetta 1 argomenti"? – Justin
Dove si trova l'errore? Assicurati che il numero di parametri sulla definizione del gestore di eventi sia coerente con il modo in cui definisci il gestore (e utilizzalo). Sto usando un Lambda con RelayCommand per aumentare l'evento nel mio esempio. –