MVVM и свойство TextBox's SelectedText

У меня есть TextBox с ContextMenu в нем. Когда пользователь щелкает правой кнопкой в TextBox и выбирает соответствующий MenuItem, я хотел бы захватить SelectedText в своем viewmodel. Я не нашел хороший способ сделать это путь "MVVM".

До сих пор у меня есть свое приложение, использующее способ Josh Smith MVVM. Я обращаюсь к передаче для Обеспечивания. Не уверенный, если платформа Подпруги обработает проблемы как это. Мысли?

13
задан Eric 11 February 2010 в 16:33
поделиться

2 ответа

Не существует прямого способа привязать SelectedText к источнику данных, поскольку это не DependencyProperty... однако, довольно легко создать вложенное свойство, которое можно привязать вместо этого.

Вот базовая реализация :

public static class TextBoxHelper
{

    public static string GetSelectedText(DependencyObject obj)
    {
        return (string)obj.GetValue(SelectedTextProperty);
    }

    public static void SetSelectedText(DependencyObject obj, string value)
    {
        obj.SetValue(SelectedTextProperty, value);
    }

    // Using a DependencyProperty as the backing store for SelectedText.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty SelectedTextProperty =
        DependencyProperty.RegisterAttached(
            "SelectedText",
            typeof(string),
            typeof(TextBoxHelper),
            new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, SelectedTextChanged));

    private static void SelectedTextChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
    {
        TextBox tb = obj as TextBox;
        if (tb != null)
        {
            if (e.OldValue == null && e.NewValue != null)
            {
                tb.SelectionChanged += tb_SelectionChanged;
            }
            else if (e.OldValue != null && e.NewValue == null)
            {
                tb.SelectionChanged -= tb_SelectionChanged;
            }

            string newValue = e.NewValue as string;

            if (newValue != null && newValue != tb.SelectedText)
            {
                tb.SelectedText = newValue as string;
            }
        }
    }

    static void tb_SelectionChanged(object sender, RoutedEventArgs e)
    {
        TextBox tb = sender as TextBox;
        if (tb != null)
        {
            SetSelectedText(tb, tb.SelectedText);
        }
    }

}

Затем вы можете использовать это в XAML :

<TextBox Text="{Binding Message}" u:TextBoxHelper.SelectedText="{Binding SelectedText}" />
20
ответ дан 1 December 2019 в 22:07
поделиться

Примеры приложений в WPF Application Framework (WAF) выбрали другой способ решения этой проблемы. Здесь ViewModel разрешен доступ к View через интерфейс (IView), и поэтому он может запрашивать текущий SelectedText.

Я считаю, что привязку не следует использовать в каждом сценарии. Иногда написание нескольких строк кода намного чище, чем использование высокоразвитых вспомогательных классов. Но это только мое мнение: -)

jbe

2
ответ дан 1 December 2019 в 22:07
поделиться
Другие вопросы по тегам:

Похожие вопросы: