如何将 cultureinfo(语言)属性 应用于 WPF richtextbox 选择
How to apply cultureinfo (language) property to WPF richtextbox selection
我通常可以在网络上的某个地方找到解决方案,主要是在 SO 上。我已经尝试了两天来解决这个问题,所有尝试都产生了完全相同的结果。希望这里有人可以提供我需要的帮助。
我没有在应用程序的任何地方添加任何语言代码,除了在组合框中,用户可以在组合框中 select 语言和下拉事件,当他们 select 下面看到的语言遵循以下定义时实时出价。
下面是 richtextbox
的 xaml 定义
<RichTextBox Name="rtbDoc" IsDocumentEnabled="true" Padding="4"
MinHeight="350" HorizontalAlignment="Stretch"
VerticalAlignment="Stretch" SpellCheck.IsEnabled="True" VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Auto" AcceptsTab="True" IsTabStop="False"
IsVisibleChanged="rtbDoc_IsVisibleChanged"
KeyUp="rtbDoc_KeyUp" PreviewMouseUp="rtbDoc_MouseUp" PreviewMouseDown="rtbDoc_PreviewMouseDown"
PreviewKeyDown="rtbDocPreviewKeyDown"
ContextMenuOpening="rtb_ContextMenuOpening"
ToolTip="Edit documents" Width="941" >
下面是应该应用语言的事件中的代码,但仅更改拼写检查器,不仅针对 selected 文本,而且针对整个文档。
private void cbbLanguage_DropDownClosed(object sender, EventArgs e)
{
if (this.cbbLanguage.SelectedIndex < 0) { return; }
int iLcid = (int)this.cbbLanguage.SelectedValue;
_ci = new System.Globalization.CultureInfo(iLcid);
// following does not seem to have any desire affect
//System.Threading.Thread.CurrentThread.CurrentCulture = _ci;
//System.Threading.Thread.CurrentThread.CurrentUICulture = _ci;
//CultureInfo ci2 = CultureInfo.CreateSpecificCulture(_ci.Name);
// both of following changes only spellchecker for document so that all English text underlined
//InputLanguageManager.SetInputLanguage(this.rtbDoc, CultureInfo.CreateSpecificCulture(ci2.Name));
//XmlLanguage xl = this.rtbDoc.Document.Language;
int iIdx = this.cbbLanguage.SelectedIndex;
DataRowView drv = this.cbbLanguage.SelectedItem as DataRowView;
DataRow[] dr = _dtLanguages.Select("LanguageId = " + drv[0].ToString()); // number id of language selected
XmlLanguage xl2 = XmlLanguage.GetLanguage(dr[0]["LanguageName"].ToString());
// this works in changing the property and all words in document
// become underlined indicating spellchecker changed but text remained English
//this.rtbDoc.Language = xl2;
if (this.rtbDoc.Selection.Text.Length > 1)
{
// this works to immediately (no focus change necessary) to
// change the property and the spellchecker shows the entire
// doc content misspelled, but the selected text remains english
this.rtbDoc.Selection.ApplyPropertyValue(FrameworkElement.LanguageProperty, xl2);
}
}
您可以处理 rtbDoc
中的 GotFocus
和 LostFocus
事件并更改 InputLanguageManager
。
<RichTextBox Name="rtbDoc" IsDocumentEnabled="true" Padding="4"
GotFocus="ChangeLanguage"
LostFocus="ChangeToDefault"
MinHeight="350" HorizontalAlignment="Stretch"
VerticalAlignment="Stretch" SpellCheck.IsEnabled="True" VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Auto" AcceptsTab="True" IsTabStop="False"
IsVisibleChanged="rtbDoc_IsVisibleChanged"
KeyUp="rtbDoc_KeyUp" PreviewMouseUp="rtbDoc_MouseUp" PreviewMouseDown="rtbDoc_PreviewMouseDown"
PreviewKeyDown="rtbDocPreviewKeyDown"
ContextMenuOpening="rtb_ContextMenuOpening"
ToolTip="Edit documents" Width="941" >
在代码中
public CultureInfo defaultLanguage;
public CultureInfo ci;
private void cbbLanguage_DropDownClosed(object sender, EventArgs e)
{
int iLcid = Int32.Parse(_lstLanguages[this.cbbLanguage.SelectedIndex].LanguageId);
ci = new System.Globalization.CultureInfo(iLcid);
System.Threading.Thread.CurrentThread.CurrentCulture = ci;
System.Threading.Thread.CurrentThread.CurrentUICulture = ci;
CultureInfo ci2 = CultureInfo.CreateSpecificCulture(ci.Name);
//InputLanguageManager.SetInputLanguage(this.rtbDoc, CultureInfo.CreateSpecificCulture(ci2.Name));
XmlLanguage xl = this.rtbDoc.Document.Language;
XmlLanguage xl2 = XmlLanguage.GetLanguage(ci2.IetfLanguageTag);
// this works in changing the property but nothing changes in the doc
this.rtbDoc.Language = xl2;
if (this.rtbDoc.Selection.Text.Length > 1)
{
// this works to change the property and the spellchecker shows the entire
// doc content misspelled, but the selected text remains english
this.rtbDoc.Selection.ApplyPropertyValue(FrameworkElement.LanguageProperty, xl2);
}
}
private void ChangeLanguage(object sender, RoutedEventArgs e)
{
defaultLanguage = InputLanguageManager.Current.CurrentInputLanguage;
InputLanguageManager.Current.CurrentInputLanguage = CultureInfo.CreateSpecificCulture(ci.Name);
}
private void ChangeToDefault(object sender, RoutedEventArgs e)
{
InputLanguageManager.Current.CurrentInputLanguage = defaultLanguage;
在获得 Shloime Rosenblum 先生的帮助后,我修改了我的代码并在此处发布给可能寻求相同解决方案的其他人。首先,无法更改选择中的现有文本。更好的解决方案是允许用户在键入时切换语言。下面的代码可以让这件事顺利而立即地完成。
首先为组合框构建列表。我选择使用 table 而不是带有 class 的列表,因为对我来说这更直观、更简单。
private void LoadLanguages()
{
CultureInfo[] ciCultures = CultureInfo.GetCultures(CultureTypes.AllCultures);
// create table
_dtLanguages = new DataTable();
_dtLanguages.Columns.Add("LanguageId", typeof(int));
_dtLanguages.Columns.Add("LanguageName", typeof(string));
_dtLanguages.Columns.Add("LanguageDisplayName", typeof(string));
// populate table
foreach ( CultureInfo ci in ciCultures)
{
DataRow dr = _dtLanguages.NewRow();
dr["LanguageId"] = ci.LCID;
dr["LanguageName"] = ci.Name;
dr["LanguageDisplayName"] = ci.DisplayName + "(" + ci.NativeName + ")";
_dtLanguages.Rows.Add(dr);
}
try
{
_dtLanguages.DefaultView.Sort = "LanguageDisplayName ASC";
this.cbbLanguage.ItemsSource = _dtLanguages.DefaultView;
this.cbbLanguage.DisplayMemberPath = "LanguageDisplayName";
this.cbbLanguage.SelectedValuePath = "LanguageId";
}
catch (Exception ex)
{
int i = ex.Message.Length;
}
return;
}
然后为用户选择语言添加 selectionchanged 事件。
private void cbbLanguage_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (e.AddedItems.Count == 0) { return; }
// set language for rtb
DataRowView drv = e.AddedItems[0] as DataRowView;
DataRow[] dr = _dtLanguages.Select("LanguageId = " + drv[0].ToString()); // number id of language selected
XmlLanguage xl2 = XmlLanguage.GetLanguage(dr[0]["LanguageName"].ToString());
this.rtbDoc.Language = xl2;
// set keyboard to match language setting; language must exactly match
// a keyboard defined in Windows.Control Panel.Language.Keyboards
int iLcid = (int)this.cbbLanguage.SelectedValue;
CultureInfo ci = new System.Globalization.CultureInfo(iLcid);
InputLanguageManager.Current.CurrentInputLanguage = CultureInfo.CreateSpecificCulture(ci.Name);
// rtb applies changes when receiving focus
this.rtbDoc.Focus();
}
用户选择语言并开始输入新语言,直到他选择另一种语言。无需更改 rtb 的 xaml 代码,也无需更改 rtb 焦点的事件。
我通常可以在网络上的某个地方找到解决方案,主要是在 SO 上。我已经尝试了两天来解决这个问题,所有尝试都产生了完全相同的结果。希望这里有人可以提供我需要的帮助。
我没有在应用程序的任何地方添加任何语言代码,除了在组合框中,用户可以在组合框中 select 语言和下拉事件,当他们 select 下面看到的语言遵循以下定义时实时出价。
下面是 richtextbox
的 xaml 定义 <RichTextBox Name="rtbDoc" IsDocumentEnabled="true" Padding="4"
MinHeight="350" HorizontalAlignment="Stretch"
VerticalAlignment="Stretch" SpellCheck.IsEnabled="True" VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Auto" AcceptsTab="True" IsTabStop="False"
IsVisibleChanged="rtbDoc_IsVisibleChanged"
KeyUp="rtbDoc_KeyUp" PreviewMouseUp="rtbDoc_MouseUp" PreviewMouseDown="rtbDoc_PreviewMouseDown"
PreviewKeyDown="rtbDocPreviewKeyDown"
ContextMenuOpening="rtb_ContextMenuOpening"
ToolTip="Edit documents" Width="941" >
下面是应该应用语言的事件中的代码,但仅更改拼写检查器,不仅针对 selected 文本,而且针对整个文档。
private void cbbLanguage_DropDownClosed(object sender, EventArgs e)
{
if (this.cbbLanguage.SelectedIndex < 0) { return; }
int iLcid = (int)this.cbbLanguage.SelectedValue;
_ci = new System.Globalization.CultureInfo(iLcid);
// following does not seem to have any desire affect
//System.Threading.Thread.CurrentThread.CurrentCulture = _ci;
//System.Threading.Thread.CurrentThread.CurrentUICulture = _ci;
//CultureInfo ci2 = CultureInfo.CreateSpecificCulture(_ci.Name);
// both of following changes only spellchecker for document so that all English text underlined
//InputLanguageManager.SetInputLanguage(this.rtbDoc, CultureInfo.CreateSpecificCulture(ci2.Name));
//XmlLanguage xl = this.rtbDoc.Document.Language;
int iIdx = this.cbbLanguage.SelectedIndex;
DataRowView drv = this.cbbLanguage.SelectedItem as DataRowView;
DataRow[] dr = _dtLanguages.Select("LanguageId = " + drv[0].ToString()); // number id of language selected
XmlLanguage xl2 = XmlLanguage.GetLanguage(dr[0]["LanguageName"].ToString());
// this works in changing the property and all words in document
// become underlined indicating spellchecker changed but text remained English
//this.rtbDoc.Language = xl2;
if (this.rtbDoc.Selection.Text.Length > 1)
{
// this works to immediately (no focus change necessary) to
// change the property and the spellchecker shows the entire
// doc content misspelled, but the selected text remains english
this.rtbDoc.Selection.ApplyPropertyValue(FrameworkElement.LanguageProperty, xl2);
}
}
您可以处理 rtbDoc
中的 GotFocus
和 LostFocus
事件并更改 InputLanguageManager
。
<RichTextBox Name="rtbDoc" IsDocumentEnabled="true" Padding="4"
GotFocus="ChangeLanguage"
LostFocus="ChangeToDefault"
MinHeight="350" HorizontalAlignment="Stretch"
VerticalAlignment="Stretch" SpellCheck.IsEnabled="True" VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Auto" AcceptsTab="True" IsTabStop="False"
IsVisibleChanged="rtbDoc_IsVisibleChanged"
KeyUp="rtbDoc_KeyUp" PreviewMouseUp="rtbDoc_MouseUp" PreviewMouseDown="rtbDoc_PreviewMouseDown"
PreviewKeyDown="rtbDocPreviewKeyDown"
ContextMenuOpening="rtb_ContextMenuOpening"
ToolTip="Edit documents" Width="941" >
在代码中
public CultureInfo defaultLanguage;
public CultureInfo ci;
private void cbbLanguage_DropDownClosed(object sender, EventArgs e)
{
int iLcid = Int32.Parse(_lstLanguages[this.cbbLanguage.SelectedIndex].LanguageId);
ci = new System.Globalization.CultureInfo(iLcid);
System.Threading.Thread.CurrentThread.CurrentCulture = ci;
System.Threading.Thread.CurrentThread.CurrentUICulture = ci;
CultureInfo ci2 = CultureInfo.CreateSpecificCulture(ci.Name);
//InputLanguageManager.SetInputLanguage(this.rtbDoc, CultureInfo.CreateSpecificCulture(ci2.Name));
XmlLanguage xl = this.rtbDoc.Document.Language;
XmlLanguage xl2 = XmlLanguage.GetLanguage(ci2.IetfLanguageTag);
// this works in changing the property but nothing changes in the doc
this.rtbDoc.Language = xl2;
if (this.rtbDoc.Selection.Text.Length > 1)
{
// this works to change the property and the spellchecker shows the entire
// doc content misspelled, but the selected text remains english
this.rtbDoc.Selection.ApplyPropertyValue(FrameworkElement.LanguageProperty, xl2);
}
}
private void ChangeLanguage(object sender, RoutedEventArgs e)
{
defaultLanguage = InputLanguageManager.Current.CurrentInputLanguage;
InputLanguageManager.Current.CurrentInputLanguage = CultureInfo.CreateSpecificCulture(ci.Name);
}
private void ChangeToDefault(object sender, RoutedEventArgs e)
{
InputLanguageManager.Current.CurrentInputLanguage = defaultLanguage;
在获得 Shloime Rosenblum 先生的帮助后,我修改了我的代码并在此处发布给可能寻求相同解决方案的其他人。首先,无法更改选择中的现有文本。更好的解决方案是允许用户在键入时切换语言。下面的代码可以让这件事顺利而立即地完成。
首先为组合框构建列表。我选择使用 table 而不是带有 class 的列表,因为对我来说这更直观、更简单。
private void LoadLanguages()
{
CultureInfo[] ciCultures = CultureInfo.GetCultures(CultureTypes.AllCultures);
// create table
_dtLanguages = new DataTable();
_dtLanguages.Columns.Add("LanguageId", typeof(int));
_dtLanguages.Columns.Add("LanguageName", typeof(string));
_dtLanguages.Columns.Add("LanguageDisplayName", typeof(string));
// populate table
foreach ( CultureInfo ci in ciCultures)
{
DataRow dr = _dtLanguages.NewRow();
dr["LanguageId"] = ci.LCID;
dr["LanguageName"] = ci.Name;
dr["LanguageDisplayName"] = ci.DisplayName + "(" + ci.NativeName + ")";
_dtLanguages.Rows.Add(dr);
}
try
{
_dtLanguages.DefaultView.Sort = "LanguageDisplayName ASC";
this.cbbLanguage.ItemsSource = _dtLanguages.DefaultView;
this.cbbLanguage.DisplayMemberPath = "LanguageDisplayName";
this.cbbLanguage.SelectedValuePath = "LanguageId";
}
catch (Exception ex)
{
int i = ex.Message.Length;
}
return;
}
然后为用户选择语言添加 selectionchanged 事件。
private void cbbLanguage_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (e.AddedItems.Count == 0) { return; }
// set language for rtb
DataRowView drv = e.AddedItems[0] as DataRowView;
DataRow[] dr = _dtLanguages.Select("LanguageId = " + drv[0].ToString()); // number id of language selected
XmlLanguage xl2 = XmlLanguage.GetLanguage(dr[0]["LanguageName"].ToString());
this.rtbDoc.Language = xl2;
// set keyboard to match language setting; language must exactly match
// a keyboard defined in Windows.Control Panel.Language.Keyboards
int iLcid = (int)this.cbbLanguage.SelectedValue;
CultureInfo ci = new System.Globalization.CultureInfo(iLcid);
InputLanguageManager.Current.CurrentInputLanguage = CultureInfo.CreateSpecificCulture(ci.Name);
// rtb applies changes when receiving focus
this.rtbDoc.Focus();
}
用户选择语言并开始输入新语言,直到他选择另一种语言。无需更改 rtb 的 xaml 代码,也无需更改 rtb 焦点的事件。