在 WPF 中创建启动器

Creating a launcher in WPF

我目前正在编写启动器,并且处于原型设计阶段。

我是 WPF 的新手,但不是 MVVM 架构的新手,但是,我不确定如何将我的 ViewModel 绑定到 CommandBox 视图,因为我在我的 ViewModel 中使用方法,也许我正在寻找从错误的角度看它所以如果我做错了什么请赐教! :)

我有以下 ViewModel,就其输入而言,它基本上是启动器的本质:

/// <summary>
/// Provides a buffer of characters in order to search for candidates that matches the buffer.
/// </summary>
public class CommandBufferViewModel : INotifyPropertyChanged
{
    private readonly StringBuilder _input;

    public CommandBufferViewModel()
    {
        _input = new StringBuilder();
    }

    public event PropertyChangedEventHandler PropertyChanged;

    /// <summary>
    /// Deletes a character from the buffer.
    /// </summary>
    public void DeleteKey(int index, int length = 1)
    {
        _input.Remove(index, length);

        OnPropertyChanged(nameof(DeleteKey));
    }

    /// <summary>
    /// Adds a character to the buffer.
    /// </summary>
    public void ProcessKey(int index, char key)
    {
        _input.Insert(index, key);

        OnPropertyChanged(nameof(ProcessKey));
    }

    /// <summary>
    /// Returns results that matches the current buffer.
    /// </summary>
    /// <returns>Results that matches the current buffer.</returns>
    public async Task<CommandResults> Search()
    {
        // NYI

        return default(CommandResults);
    }

    protected virtual void OnPropertyChanged(string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

这里的想法是命令可以存储在远程数据库或您可能喜欢的任何存储以及本地。

(CommandBox 视图)文本框如下所示:

<TextBox
    x:Class="Yalla.Launcher.Views.CommandBox"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
    xmlns:bs="clr-namespace:Yalla.Launcher.Behaviors"
    mc:Ignorable="d" 
    Width="Auto" Height="Auto" VerticalContentAlignment="Center" BorderThickness="1">
    <i:Interaction.Behaviors>
        <bs:WatermarkBehavior Text="Enter Command... (type ? for help)" />
    </i:Interaction.Behaviors>
</TextBox>

我想我明白了,我将简单地拥有一个 ViewModel 来保存用户正在搜索的命令的文本,我将使用它作为视图和搜索服务之间的粘合剂启动器。

像这样:

namespace Yalla.Launcher.ViewModels
{
    using System.ComponentModel;

    using Commands;

    using Features.Commands.Search;

    public class SearchViewModel : INotifyPropertyChanged, ISearchableText
    {
        private SearchCommandHandler _enterCommandHandler;

        private string _searchText;

        public event PropertyChangedEventHandler PropertyChanged;

        public SearchCommandHandler Search => _enterCommandHandler ?? (_enterCommandHandler = new SearchCommandHandler(new SearchService(this)));

        public string SearchText
        {
            get
            {
                return _searchText;
            }

            set
            {
                _searchText = value;

                OnPropertyChanged(nameof(SearchText));
            }
        }

        protected virtual void OnPropertyChanged(string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

最后,我像这样将它绑定到 TextBox:

<ctrls:LauncherTextBox
    x:Class="Yalla.Launcher.Views.LauncherSearchBox"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
    xmlns:bs="clr-namespace:Yalla.Launcher.Behaviors"
    xmlns:ctrls="clr-namespace:Yalla.Launcher.Controls"
    xmlns:vm="clr-namespace:Yalla.Launcher.ViewModels"
    mc:Ignorable="d"
    Width="Auto" Height="Auto" 
    VerticalContentAlignment="Center" BorderThickness="1" 
    Text="{Binding SearchText, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
    <ctrls:LauncherTextBox.DataContext>
        <vm:SearchViewModel />
    </ctrls:LauncherTextBox.DataContext>
    <i:Interaction.Behaviors>
        <bs:WatermarkBehavior Text="Enter Command... (type ? for help)" />
    </i:Interaction.Behaviors>
    <TextBox.InputBindings>
        <KeyBinding Key="Return" Command="{Binding Search}"></KeyBinding>
    </TextBox.InputBindings>
</ctrls:LauncherTextBox>

很简单,但这可能是我需要开始的。