3

我正在尝试为遵循 MVVM 模式的 wpf 应用程序实现帮助功能。我有我的帮助文件,其中包含根据应用程序的许多页面。现在我需要将它集成到我的应用程序中。

以下是我的要求:

  1. 根据视图模型,按 F1 会在帮助文件中打开特定页面。为此,我想,我需要将 F1 命令绑定到我的视图模型。我们如何在视图中绑定键?
  2. 在文本字段上按 F1 可打开该文本字段的帮助。我认为这与要求 1 相同。但这里的问题是我如何知道选择了某个文本字段、按钮或单选按钮?
4

1 回答 1

2
  1. 侦听视图(或视图的基类)中的键并在 DataContext 上的 HelpCommand 上调用 execute。

  2. 将具有焦点的控件(或其 id 或标记...)作为参数传递给 HelpCommand 。

使用 FocusManager查找焦点控件的替代方法

这是一个例子:

上下文帮助 C#:

public static class ContextHelp
{
    public static readonly DependencyProperty KeywordProperty =
        DependencyProperty.RegisterAttached(
            "Keyword",
            typeof(string),
            typeof(ContextHelp));

    public static void SetKeyword(UIElement target, string value)
    {
        target.SetValue(KeywordProperty, value);
    }

    public static string GetKeyword(UIElement target)
    {
        return (string)target.GetValue(KeywordProperty);
    }
}

视图库:

public abstract class ViewBase : UserControl
{
    public ViewBase()
    {
        this.KeyUp += ViewBase_KeyUp;
        this.GotFocus += ViewBase_GotFocus;
    }

    void ViewBase_GotFocus(object sender, RoutedEventArgs e)
    {
        FocusManager.SetIsFocusScope(this, true);
    }

    void ViewBase_KeyUp(object sender, System.Windows.Input.KeyEventArgs e)
    {
        if (e.Key == Key.F1)
        {
            var viewModel = this.DataContext as ViewModelBase;
            if (viewModel != null)
            {
                var helpTopic = "Index";
                var focusedElement = 
                    FocusManager.GetFocusedElement(this) as FrameworkElement;
                if (focusedElement != null)
                {
                    var keyword = ContextHelp.GetKeyword(focusedElement);
                    if (!String.IsNullOrWhiteSpace(keyword))
                    {
                        helpTopic = keyword;
                    }
                }
                viewModel.HelpCommand.Execute(helpTopic);
            }
        }
    }
}

视图模型库:

public abstract class ViewModelBase: INotifyPropertyChanged
{
    public ICommand HelpCommand { get; set; }

    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged([CallerMemberName] string propertyName="")
    {
        var p = PropertyChanged;
        if (p != null)
        {
            p(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

视图模型:

class AViewModel : ViewModelBase
{
    public AViewModel()
    {
        HelpCommand = new RelayCommand(HelpCommandExecuted, (p)=>true);
    }

    private void HelpCommandExecuted(object parameter)
    {
        var topic = parameter as string;
        if (!String.IsNullOrWhiteSpace(topic))
        {
            HelpText = String.Format("Information on the interesting topic: {0}.", topic);
        }
    }

    private string _helpText;

    public string HelpText
    {
        get { return _helpText; }
        private set
        {
            if (_helpText != value)
            {
                _helpText = value;
                OnPropertyChanged();
            }
        }
    }
}

AView C#:

public partial class AView : ViewBase
{
    public AView()
    {
        InitializeComponent();
    }
}

查看 XAML:

<local:ViewBase x:Class="WpfApplication2.AView"
             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:local="clr-namespace:WpfApplication2"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <Grid>
        <Label Content="{Binding HelpText}" Margin="10,254,10,0" VerticalAlignment="Top" Height="36"/>
        <Button local:ContextHelp.Keyword="Button Info" Content="Button" HorizontalAlignment="Left" Margin="192,32,0,0" VerticalAlignment="Top" Width="75"/>
        <TextBox local:ContextHelp.Keyword="TextBox Info" HorizontalAlignment="Left" Height="23" Margin="29,32,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="120"/>
        <CheckBox local:ContextHelp.Keyword="CheckBox Info" Content="CheckBox" HorizontalAlignment="Left" Margin="29,80,0,0" VerticalAlignment="Top"/>
        <ComboBox local:ContextHelp.Keyword="ComboBox Info" HorizontalAlignment="Left" Margin="138,80,0,0" VerticalAlignment="Top" Width="120"/>
    </Grid>
</local:ViewBase>

主窗口 XAML:

<Window
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfApplication2" x:Class="WpfApplication2.MainWindow"
        Title="MainWindow" Height="700" Width="500">
    <Grid x:Name="ViewPlaceholder">
    </Grid>
</Window>

主窗口 C#:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        var view = new AView();
        var viewModel = new AViewModel();
        view.DataContext = viewModel;
        ViewPlaceholder.Children.Clear();
        ViewPlaceholder.Children.Add(view);
    }
}
于 2013-06-10T10:53:18.317 回答