【问题标题】:Windows language independent command shortcuts for text editing用于文本编辑的独立于 Windows 语言的命令快捷方式
【发布时间】:2014-09-10 07:31:58
【问题描述】:

我有一个要求,即相同的键盘快捷键必须以相同的方式在 WPF 富文本框中设置文本属性,而与安装的语言窗口无关。

快捷方式:

  • CTRL+B:使文本加粗
  • CTRL+I:使文本变为斜体
  • CTRL+SHIFT+S:删除线文本

尽管这无关紧要,因为所有操作系统语言的行为方式都必须相同,但使用的本地语言有:EN-US、DE-DE、DE-CH、FR-FR、FR-CH、IT -IT,IT-CH

为了实现这个功能,已经尽早在App.xaml.cs的构造函数中添加了以下代码:

public App() {
   Thread.CurrentThread.Name = "Main";

   m_log.Info("Starting application");

   // Assign command bindings to be OS language independent
   EditingCommands.ToggleBold.InputGestures.Clear();
   EditingCommands.ToggleBold.InputGestures.Add(new KeyGesture(Key.B, ModifierKeys.Control));

   EditingCommands.ToggleItalic.InputGestures.Clear();
   EditingCommands.ToggleItalic.InputGestures.Add(new KeyGesture(Key.I, ModifierKeys.Control));

   TextFormattingCommands.ToggleStrikethrough.InputGestures.Clear();
   TextFormattingCommands.ToggleStrikethrough.InputGestures.Add(new KeyGesture(Key.S, ModifierKeys.Control | ModifierKeys.Shift));

   InitializeComponent();
}

一些观察:

  • 对于我的 EN-US 系统,CTRL+B 和 CTRL+I 都没有使用上述代码,因为这些是默认快捷方式。
  • 使用上面的代码,CTRL+SHIFT+S 使删除线(不存在开箱即用)按预期工作。
  • 在 DE-DE 系统上测试时,CTRL+I 和 CTRL+SHIFT+S 有效,但 CTRL+B 无效。
  • 实际上并不需要在设置之前清除输入手势,因为此时所有上述命令的 InputGestures 都是空的。
  • 已在 Win7 x64 上进行了测试,但应独立于使用的 Windows 版本运行

问题:如何保证这些编辑快捷方式的行为方式与安装的操作系统语言无关?

[编辑]这是使用CommandBindings 的DataTemplate 的相关部分:

<DataTemplate x:Key="QualificationTextItemTemplate" DataType="DienstleistenderQualifikationMerkmaleEntity">
    <GroupBox>
        <Grid HorizontalAlignment="Stretch">
            <Grid.ColumnDefinitions>
                <ColumnDefinition SharedSizeGroup="MerkmaleColumn" MinWidth="480"
                                              Width="{Binding Path=ActualWidth, ConverterParameter=0.4,
                                                              RelativeSource={RelativeSource AncestorType=ListView, Mode=FindAncestor},
                                                              Converter={x:Static qualifikationen:QualificationItemFreeRichTextBoxWidthConverter.Instance}}"/>
                <ColumnDefinition SharedSizeGroup="OhneBeurteilungColumn" MinWidth="128"
                                              Width="{Binding Path=ActualWidth, ConverterParameter=0.1,
                                                              RelativeSource={RelativeSource AncestorType=ListView, Mode=FindAncestor},
                                                              Converter={x:Static qualifikationen:QualificationItemFreeRichTextBoxWidthConverter.Instance}}"/>
                <ColumnDefinition SharedSizeGroup="BeurteilungColumn" MinWidth="128"
                                              Width="{Binding Path=ActualWidth, ConverterParameter=0.1,
                                                              RelativeSource={RelativeSource AncestorType=ListView, Mode=FindAncestor},
                                                              Converter={x:Static qualifikationen:QualificationItemFreeRichTextBoxWidthConverter.Instance}}"/>
                <ColumnDefinition SharedSizeGroup="BemerkungColumn"
                                              Width="{Binding Path=ActualWidth, ConverterParameter=0.4,
                                                              RelativeSource={RelativeSource AncestorType=ListView, Mode=FindAncestor},
                                                              Converter={x:Static qualifikationen:QualificationItemFreeRichTextBoxWidthConverter.Instance}}"/>
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition />
                <RowDefinition />
            </Grid.RowDefinitions>
            [...]
            <UIControls:BindableRichTextBox Grid.Row="1" 
                                                        Grid.Column="0" 
                                                        Height="Auto" 
                                                        VerticalAlignment="Stretch" 
                                                        Margin="15 0 10 0"
                                                        SpellCheck.IsEnabled="False" 
                                                        MaxLength="2000"
                                                        DisplayedTextToBoundTextConverter="{x:Static qualifikationen:QualificationItemDescriptionValueConverter.XamlToMILOFormatConverter}"                                                        
                                                        BoundTextToDisplayedTextConverter="{x:Static qualifikationen:QualificationItemDescriptionValueConverter.MILOFormatToXamlConverter}"
                                                        Text="{Binding Path=Verhaltensmerkmal, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                                                        TextChangedManually="OnQualificationItemPropertyChanged" VerticalScrollBarVisibility="Auto">
                <RichTextBox.Resources>
                    <Style TargetType="{x:Type Paragraph}">
                        <Setter Property="Margin" Value="0"/>
                    </Style>
                </RichTextBox.Resources>
                <Control.Visibility>
                    <MultiBinding Converter="{x:Static qualifikationen:QualificationItemDescriptionVisibilityConverter.Instance}">
                        <Binding Path="QualifikationItem.ItemStyle" Mode="OneTime" />
                        <Binding Path="QualifikationItem.Protected" Mode="OneTime" />
                        <Binding Path="QualifikationItem.Description" Mode="OneTime" />
                    </MultiBinding>
                </Control.Visibility>
                <TextBoxBase.IsReadOnly>
                    <MultiBinding Converter="{x:Static qualifikationen:QualificationItemDescriptionReadOnlyConverter.Instance}">
                        <Binding Path="Visibility" RelativeSource="{RelativeSource Mode=Self}" />
                        <Binding Path="QualifikationItem.Protected" Mode="OneWay" />
                        <Binding Path="Beurteilt" />
                    </MultiBinding>
                </TextBoxBase.IsReadOnly>
                <RichTextBox.InputBindings>
                    <KeyBinding Command="ApplicationCommands.NotACommand" Key="U" Modifiers="Control"/>
                    <KeyBinding Command="ApplicationCommands.NotACommand" Key="L" Modifiers="Control"/>
                    <KeyBinding Command="ApplicationCommands.NotACommand" Key="E" Modifiers="Control"/>
                    <KeyBinding Command="ApplicationCommands.NotACommand" Key="R" Modifiers="Control"/>
                    <KeyBinding Command="ApplicationCommands.NotACommand" Key="OemCloseBrackets" Modifiers="Control"/>
                    <KeyBinding Command="ApplicationCommands.NotACommand" Key="OemOpenBrackets" Modifiers="Control"/>
                </RichTextBox.InputBindings>
                <RichTextBox.CommandBindings>
                    <CommandBinding Command="EditingCommands.ToggleBold"
                                                CanExecute="OnRichTextBoxEditingCommandsCanExecuteChecked" 
                                                Executed="OnRichTextBoxToggleBoldCommandExecuted"/>
                    <CommandBinding Command="EditingCommands.ToggleItalic"
                                                CanExecute="OnRichTextBoxEditingCommandsCanExecuteChecked" 
                                                Executed="OnRichTextBoxToggleItalicCommandExecuted"/>
                    <CommandBinding Command="FormattingCommands:TextFormattingCommands.ToggleStrikethrough"
                                                CanExecute="OnRichTextBoxEditingCommandsCanExecuteChecked" 
                                                Executed="OnRichTextBoxToggleStrikethroughCommandExecuted"/>
                </RichTextBox.CommandBindings>
                <Control.ContextMenu>
                    <ContextMenu>
                        <MenuItem Header="{rootLoc:LocText Dict=Resources, Key=ContextMenuCutHeader}" Command="ApplicationCommands.Cut"/>
                        <MenuItem Header="{rootLoc:LocText Dict=Resources, Key=ContextMenuCopyHeader}" Command="ApplicationCommands.Copy"/>
                        <MenuItem Header="{rootLoc:LocText Dict=Resources, Key=ContextMenuPasteHeader}" Command="ApplicationCommands.Paste"/>
                        <Separator />
                        <MenuItem Header="{LocText CommonResources:BoldButtonText}"
                                              Command="EditingCommands.ToggleBold" 
                                              InputGestureText="Ctrl+B"/>
                        <MenuItem Header="{LocText CommonResources:ItalicButtonText}"
                                              Command="EditingCommands.ToggleItalic" 
                                              InputGestureText="Ctrl+I"/>
                        <MenuItem Header="{LocText CommonResources:StrokeButtonText}"
                                              Command="FormattingCommands:TextFormattingCommands.ToggleStrikethrough"
                                              InputGestureText="Ctrl+Shift+S"/>
                    </ContextMenu>
                </Control.ContextMenu>
            </UIControls:BindableRichTextBox>
            [...]
        </Grid>
    </GroupBox>
</DataTemplate>

[edit2] 在 DE-DE 机器上(CTRL+B 不起作用),相同的快捷方式在写字板中起作用。不确定写字板是否会覆盖默认快捷方式,因为我找不到有关要使用的快捷方式的任何提示。至少在 Word 中,快捷键是 CTRL+SHIFT+F (http://forum.chip.de/office/tastaturkuerzel-fuer-fett-unterstrichen-kursiv-548164.html)

[edit3] 当使用EditingCommands.ToggleBold.InputGestures.Add(new KeyGesture(Key.Q, ModifierKeys.Control)); 将输入手势更改为 CTRL+Q(只是为了测试另一个组合键)时,CTRL+Q 会使所有操作系统语言的文本变为粗体。 p>

【问题讨论】:

    标签: c# wpf windows multilingual


    【解决方案1】:

    您好,德语操作系统也有同样的问题,快捷方式也有

    您必须更改应用的文化属性 在你的 MainWindow 构造函数中试试这个

    CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("en-US"); CultureInfo.DefaultThreadCurrentUICulture = new CultureInfo("en-US");

    对于其他操作系统,我来宾您只需要更改 CultureInfo

    【讨论】:

    • 谢谢,很遗憾,我目前无法对其进行测试(由于缺少虚拟机),但一旦我能够对其进行测试,就会回复您的答案。
    • 我们使用的是 .Net3.5,CultureInfo.DefaultThreadCurrentCulture 已添加到 .Net4.5。我检查了 UI 线程的 CurrentCultureCurrentUICulture 设置是否正确(我的测试 VM 的 DE-CH),但 CTRL+B 仍然无法正常工作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多