我有一个richtextbox,我想让它像写字板一样工作。我的问题是,例如,如果我使用Calibri字体键入“123”,然后使用Arial字体键入“456”并且我想更改2345的大小,它将不允许我这样做,因为他们有两个不同的字体类型。这就是我遇到的问题:
private void combo_sizes_TextChanged(object sender, EventArgs e)
{
if (rtb.SelectionFont == null)
{
rtb.SelectionFont = new Font(combo_fonts.Text, Convert.ToInt16(combo_sizes.Text));
}
rtb.SelectionFont = new Font(rtb.SelectionFont.FontFamily, Convert.ToInt16(combo_sizes.Text));
}
我知道当rtb中的选定文本包含多个字体时,SelectionFont等于null,所以在这种情况下我已经使它从两个组合框中获取所选文本的大小和字体,但我想改变大小而不会失去它原始字体。有解决方案吗?
谢谢
打破你的selected text
到char
s。获取每个char
的字体,并更改其大小。
RichTextBox(RTB)中有两种内置字体:
Font
是任何输入之后将使用的那个。因此,如果您想切换到另一种字体,这就是您应该设置的内容SelectionFont
是当前选择的字体。这将随选择而改变,但它也用于设置已输入文本的部分字体。但是,在任何时间和地点都只能有一个。如果要切换回标准Front,则需要在某处保留标准Font。
或者您可以在List中存储您使用的所有字体,并且可以在comboBox中提供它们。
还请注意:
您的代码可能如下所示:
public Form1()
{
InitializeComponent();
lastSelectionFont = rtb.SelectionFont;
lastFont = rtb.Font;
//..
}
Font lastSelectionFont;
Font lastFont;
private void richTextBox1_TextChanged(object sender, EventArgs e)
{
if (rtb.SelectionLength > 0)
{
lastSelectionFont = rtb.SelectionFont;
rtb.SelectionFont = new Font(rtb.SelectionFont.FontFamily,
Convert.ToInt16(combo_sizes.Text));
}
else
{
lastFont = rtb.Font;
rtb.Font = new Font(rtb.Font.FontFamily,
Convert.ToInt16(combo_sizes.Text));
}
}
请注意,SelectionFont不会为null ubnless,您将其设置为null。没有选择时你可能会遇到问题。
但同样,我不确定你的“拯救”前任福恩的想法。想想wordPad:它也没有做任何想法。将您使用的所有字体添加到字体列表中,甚至可以使用theris颜色,并且字体和样式的好名称听起来非常有吸引力。
我在这里需要同样的东西。我没有找到最好的解决方案......所以,这是丑陋的解决方案。
private void UglyChangeFontSize(RichTextBox rtb, float newSize = -1f, FontFamily fontFamily = null) {
if (rtb.SelectionFont != null) {
if (newSize < 0) newSize = rtb.SelectionFont.Size;
if (fontFamily == null) fontFamily = rtb.SelectionFont.FontFamily;
rtb.SelectionFont = new Font(fontFamily, newSize, rtb.SelectionFont.Style);
}
else {
// Backup Selection
var sel = rtb.SelectionStart;
var selLen = rtb.SelectionLength;
// Change, char by char
for (int k = 0; k < selLen; k++) {
rtb.Select(sel + k, 1);
if (newSize < 0) newSize = rtb.SelectionFont.Size;
var ff = fontFamily ?? rtb.SelectionFont.FontFamily;
rtb.SelectionFont = new Font(fontFamily, newSize, rtb.SelectionFont.Style);
}
// Restore Selection
rtb.SelectionStart = sel;
rtb.SelectionLength = selLen;
}
}
改良版
这是一个更好的版本,它包括:
要求
代码
RichTextBox myRichTextBox = new RichTextBox();
RichOLE mRichOle = new RichOLE(myRichTextBox);
...
private void UglyChangeFontSize(RichTextBox rtb, float newSize = -1f, FontFamily fontFamily = null) {
if (rtb.SelectionFont != null) {
if (newSize < 0) newSize = rtb.SelectionFont.Size;
if (fontFamily == null) fontFamily = rtb.SelectionFont.FontFamily;
rtb.SelectionFont = new Font(fontFamily, newSize, rtb.SelectionFont.Style);
}
else {
Cursor = Cursors.WaitCursor;
// Hide the modifications from the user
External.LockWindowAndKeepScrollPosition(rtb, () =>
{
// Backup Selection
var sel = rtb.SelectionStart;
var selLen = rtb.SelectionLength;
// Disable UNDO for this "in pieces modifications" [START]
rtb.SelectedRtf = rtb.SelectedRtf; // Required to allow Undo
//mFontLockEvents = true; // RicherTextBox
mRichOle.EnableUndo(false);
// Disable UNDO for this "in pieces modifications" [END]
// Change, char by char
for (int k = 0; k < selLen; k++) {
rtb.Select(sel + k, 1);
// again, ugly... buuut we have Branch Prediction (google it)
if (newSize < 0) newSize = rtb.SelectionFont.Size;
var ff = fontFamily ?? rtb.SelectionFont.FontFamily;
rtb.SelectionFont = new Font(fontFamily, newSize, rtb.SelectionFont.Style);
}
// Disable UNDO for this "in pieces modifications" [START]
//mFontLockEvents = false; // RicherTextBox
mRichOle.EnableUndo(true);
// Disable UNDO for this "in pieces modifications" [END]
// Restore Selection
rtb.SelectionStart = sel;
rtb.SelectionLength = selLen;
});
Cursor = Cursors.Default;
}
}