Слияние кода завершено, страница обновится автоматически
using MahApps.Metro.Controls;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace LunarSF.SHomeWorkshop.LunarMarkdownEditor
{
/// <summary>
/// PresentationWindow.xaml 的交互逻辑
/// </summary>
public partial class PresentationWindow : Window
{
public PresentationWindow(MarkdownEditor editor)
{
InitializeComponent();
this.masterEditor = editor;
}
private MarkdownEditor masterEditor = null;
public MarkdownEditor MasterEditor
{
get { return this.masterEditor; }
}
private List<Question> questions = new List<Question>();
private int point;
public void BuildQuestions(string content)
{
this.questions.Clear();
this.point = -1;
//分解试题源文本,分解成试题列表。
if (string.IsNullOrEmpty(content))
{
this.ShowQuestion();
return;
}
int index = content.IndexOf("<信息>>>");
if (index >= 0)
{
content = content.Substring(index + 6);
}
List<string> baseQuestionStrings = new List<String>();
int previewIndex = -1;
index = content.IndexOf("试题>>");
while (index >= 0 && index < content.Length)
{
if (previewIndex > -1 && previewIndex <= index)
{
String baseQuestionText = content.Substring(previewIndex, index - previewIndex);
baseQuestionStrings.Add(baseQuestionText);
}
previewIndex = index;
index = content.IndexOf("试题>>", index + 4);
}
if (previewIndex >= 0 && index < 0)
{
// 最后一道题
baseQuestionStrings.Add(content.Substring(previewIndex));
}
else
{
baseQuestionStrings.Add(content);
}
foreach (string baseQuestionString in baseQuestionStrings)
{
List<Question> newQuestions = BaseQuestion.BuildQuestionList(baseQuestionString, cmboxFillBlankView.SelectedItem == cbiMultiFillBlankQuestions);
if (newQuestions != null)
{
this.questions.AddRange(newQuestions);
}
}
//根据是否“分拆”决定是否总体混淆排序
if (cmboxFillBlankView.SelectedItem == cbiSingleQuestion)
{
// 使用随机数混淆顺序。
int[] random = L.GetRandomIntArray(questions.Count);
foreach (int i in random)
{
questions[i].OrderNumber = random[i];
}
questions.Sort(new CmparsionQuestion());
}
if (questions.Count > 0)
{
point = 0;
}
else
{
point = -1;
}
this.ShowQuestion();//能不能显示,此方法自己可以管理。
}
private bool answerVisible = false;
/// <summary>
/// 当前是否显示了答案。
/// </summary>
public bool AnswerVisible
{
get { return this.answerVisible; }
}
private Run answerRun = null;
private TextBlock answerTextBlock;
private void ShowQuestion()
{
this.askPanel.Visibility = Visibility.Collapsed;//隐藏提问面板。
this.answerVisible = false;
this.answerParagraph = null;
this.answerParagraphList.Clear();
this.Document.Blocks.Clear();
if (this.questions.Count <= 0)
{
this.Document.Blocks.Add(new Paragraph(new Run("文档中没有任何可以显示的试题!")));
return;
}
if (this.point < 0)
{
this.Document.Blocks.Add(new Paragraph(new Run("试题指针越界(小于0)!")));
return;
}
if (this.point >= this.questions.Count)
{
this.Document.Blocks.Add(new Paragraph(new Run("试题指针越界(大于可用试题总数)!")));
return;
}
//带一对方括弧的是填充项。
var question = questions[point];
switch (question.Type)
{
case QuestionType.Judge://判断题是特殊形式的选择题。
case QuestionType.Choice:
{
ShowChoiceQuestion(question); break;
}
case QuestionType.FillBlank:
{
ShowFillBlankQuestion(question); break;
}
case QuestionType.Subjective:
{
ShowSubjectiveQuestion(question); break;
}
case QuestionType.Text:
{
ShowText(question); break;
}
}
this.Document.Focus();
}
private void ShowSubjectiveQuestion(Question question)
{
string title = question.TitleString.Replace("\r\n", "");
if (string.IsNullOrEmpty(title))
{
title = "阅读下列材料:";
}
//根据title生成段落。
var p = new Paragraph();
var container = new InlineUIContainer();
var questionNumberTextBlock = new TextBlock()
{
//Background = Brushes.Gray,
Foreground = Brushes.Red,
Padding = new Thickness(0, 0, 10, 0),
Margin = new Thickness(0, 0, 10, 0),
Text = (point + 1).ToString() + ".",
FontWeight = FontWeights.Bold,
};
container.Child = questionNumberTextBlock;
p.Inlines.Add(container);
p.Inlines.Add(title);
this.answerRun = null;//主观题没有填充项。故无此run。
this.Document.Blocks.Add(p);
//材料部分。
foreach (var s in question.Materials)
{
int indexOfcc = s.IndexOf("<<出处>>");
if (indexOfcc >= 0)
{
Paragraph newPara = new Paragraph(new Run(s.Substring(0, indexOfcc).Replace("\r\n", "")));
this.Document.Blocks.Add(newPara);
string clcc = s.Substring(indexOfcc + 6);
if (clcc.StartsWith("——") == false)
{
clcc = "——" + clcc;
}
Paragraph newParacc = new Paragraph(new Run(clcc)) { TextAlignment = TextAlignment.Right, Foreground = Brushes.DeepPink, };
this.Document.Blocks.Add(newParacc);
}
else
{
Paragraph newPara = new Paragraph(new Run(s.Replace("\r\n", "")));
this.Document.Blocks.Add(newPara);
}
}
this.Document.Blocks.Add(new Paragraph(new Run("请回答:")));
//问题部分
for (int i = 0; i < question.AsksList.Count; i++)
{
var s = question.AsksList[i];
Paragraph newPara = new Paragraph(new Run("(" + (i + 1).ToString() + ")" + s.Replace("\r\n", "")));
this.Document.Blocks.Add(newPara);
}
answerParagraph = new Paragraph(new Run("参考答案:")
{
Background = Brushes.Red,
Foreground = Brushes.White,
});
//下面是答案部分。
for (int i = 0; i < question.Answers.Count; i++)
{
var s = question.Answers[i];
int indexOfjx = s.IndexOf("解析>>");
if (indexOfjx >= 0)
{
Paragraph newPara = new Paragraph(new Run("(" + (i + 1).ToString() + ")" + s.Substring(0, indexOfjx).Replace("\r\n", "")));
this.answerParagraphList.Add(newPara);
Paragraph newParacc = new Paragraph(new Run(s.Substring(indexOfjx + 6))) { TextAlignment = TextAlignment.Right, };
this.answerParagraphList.Add(newParacc);
}
else
{
Paragraph newPara = new Paragraph(new Run("(" + (i + 1).ToString() + ")" + s.Replace("\r\n", "")));
this.answerParagraphList.Add(newPara);
}
}
tbTitle.Text = this.Title = "试题演示(" + (this.point + 1).ToString() + " ∕ " + this.questions.Count.ToString() + ")";
}
#region 主观题专用
private Paragraph answerParagraph;
private List<Paragraph> answerParagraphList = new List<Paragraph>();
#endregion
private void ShowText(Question question)
{
string title = question.TitleString;
//根据title生成段落。
var p = new Paragraph();
var container = new InlineUIContainer();
var questionNumberTextBlock = new TextBlock()
{
//Background = Brushes.Gray,
Foreground = Brushes.Red,
Padding = new Thickness(0, 0, 10, 0),
Margin = new Thickness(0, 0, 10, 0),
Text = (point + 1).ToString() + ".",
FontWeight = FontWeights.Bold,
};
container.Child = questionNumberTextBlock;
p.Inlines.Add(container);
//int startBracket, endBracket;
//startBracket = title.IndexOf("【");
//endBracket = title.IndexOf("】");
//如果根本就没有提供任何填充项,说明只是普通文本,直接输出即可。
//if (startBracket < 0 && endBracket < 0)
//{
p.Inlines.Add(title);
//}
this.Document.Blocks.Add(p);
tbTitle.Text = this.Title = "试题演示(" + (this.point + 1).ToString() + " ∕ " + this.questions.Count.ToString() + ")";
}
private void HideRightColumn()
{
rightColumn.Width = new GridLength(0);
}
private void ShowRightColumn()
{
rightColumn.Width = new GridLength(1, GridUnitType.Star);
}
private void ShowImage(string imageRelativePath)
{
if (string.IsNullOrWhiteSpace(imageRelativePath))
{
img.Source = null;
HideRightColumn();
return;
}
if (this.masterEditor == null || string.IsNullOrEmpty(this.masterEditor.FullFilePath))
{
img.Source = null;
HideRightColumn();
return;
}
var pieces = imageRelativePath.Split(new char[] { '/', '\\' }, StringSplitOptions.RemoveEmptyEntries);
if (pieces.Length <= 0)
{
img.Source = null;
HideRightColumn();
return;
}
FileInfo thisFileInfo = new FileInfo(this.MasterEditor.FullFilePath);
var directory = thisFileInfo.Directory;
int x = 0;
foreach (var s in pieces)
{
if (s == "..")
{
directory = directory.Parent;
x++;
}
else
{
var subPath = directory.FullName.EndsWith("\\") ? (directory.FullName + s) : (directory.FullName + "\\" + s);
if (Directory.Exists(subPath) == false)
{
if (WorkspaceTreeViewItem.IsValidateImageFilePath(subPath))
{
//就是目标
ShowRightColumn();
img.Source = new BitmapImage(new Uri(subPath));
return;
}
HideRightColumn();
img.Source = null;
return;
}
else
{
directory = new DirectoryInfo(subPath);
x++;
}
}
}
if (x != pieces.Length - 1)
{
HideRightColumn();
img.Source = null; return;
}
}
private void ShowFillBlankQuestion(Question question)
{
string title = question.TitleString;
ShowImage(question.MarkdownImagePath);
//根据title生成段落。
var p = new Paragraph();
var container = new InlineUIContainer();
var questionNumberTextBlock = new TextBlock()
{
//Background = Brushes.Gray,
Foreground = Brushes.Red,
Padding = new Thickness(0, 0, 10, 0),
Margin = new Thickness(0, 0, 10, 0),
Text = (point + 1).ToString() + ".",
FontWeight = FontWeights.Bold,
};
container.Child = questionNumberTextBlock;
p.Inlines.Add(container);
int previewStartBacket = -1; int previewEndBracket = -1;
int startBracket, endBracket;
startBracket = title.IndexOf("【");
endBracket = title.IndexOf("】");
while (startBracket >= 0 && endBracket >= 0)
{
p.Inlines.Add(title.Substring(previewEndBracket + 1, startBracket - previewEndBracket - 1));
p.Inlines.Add(new Span(new Run(" " + title.Substring(startBracket + 1, endBracket - startBracket - 1) + " ") { Foreground = Brushes.Transparent, })
{
Foreground = Brushes.Red,
FontWeight = FontWeights.Black,
TextDecorations = TextDecorations.Underline,
Tag = "FillBlank",
});
previewEndBracket = endBracket;
previewStartBacket = startBracket;
startBracket = title.IndexOf("【", endBracket + 1);
endBracket = title.IndexOf("】", endBracket + 1);
}
if (previewEndBracket >= 0 && previewEndBracket < title.Length - 1)
{
p.Inlines.Add(title.Substring(previewEndBracket + 1));
}
this.Document.Blocks.Add(p);
tbTitle.Text = this.Title = "试题演示(" + (this.point + 1).ToString() + " ∕ " + this.questions.Count.ToString() + ")";
//填空题十分简单,只需要显示title即可。无须添加任何选择项,也没有解析。
}
private void ShowChoiceQuestion(Question question)
{
string title = question.TitleString.Replace("\r", "").Replace("\n", "");
ShowImage(question.MarkdownImagePath);
//根据title生成段落。
int startBracket, endBracket;
startBracket = title.IndexOf("【");
endBracket = title.IndexOf("】");
if (startBracket < 0 || endBracket < 0) return;
var p = new Paragraph();
var container = new InlineUIContainer();
var questionNumberTextBlock = new TextBlock()
{
//Background = Brushes.Gray,
Foreground = Brushes.Red,
Padding = new Thickness(0, 0, 10, 0),
Text = (point + 1).ToString() + ".",
FontWeight = FontWeights.Bold,
};
container.Child = questionNumberTextBlock;
p.Inlines.Add(container);
p.Inlines.Add(title.Substring(0, startBracket));
var answerText = title.Substring(startBracket + 1, endBracket - startBracket - 1);
this.answerRun = new Run()
{
Text = "【 】",
Foreground = Brushes.Red,
//Tag = "FillBlank",//这个还是直接显示比较好
};
p.Inlines.Add(new Span(this.answerRun)
{
Foreground = Brushes.Red,
FontWeight = FontWeights.Black,
//TextDecorations = TextDecorations.Underline,
});
p.Inlines.Add(title.Substring(endBracket + 1));
this.Document.Blocks.Add(p);
//添加各选项
//先需要混淆下顺序,否则会总选A了。
int[] randomArray = L.GetRandomIntArray(question.ChoiceItems.Count);
for (int i = 0; i < randomArray.Length; i++)
{
var qi = question.ChoiceItems[i];
qi.OrderNumber = randomArray[i];
}
question.ChoiceItems.Sort(new CmparsionQuestionItem());
string answerHeaderText = "未设置答案项";
for (int i = 0; i < question.ChoiceItems.Count; i++)
{
ChoiceItem qi = question.ChoiceItems[i];
Paragraph itemParagraph = new Paragraph();
string choiceItemHeaderText = L.ConvertToAlpha(i + 1);
var choiceItemTextBlock = new TextBlock()
{
Text = choiceItemHeaderText,
FontWeight = FontWeights.Bold,
Padding = new Thickness(10, 0, 10, 0),
Margin = new Thickness(0, 0, 10, 0),
};
itemParagraph.Inlines.Add(choiceItemTextBlock);
itemParagraph.Inlines.Add(new Run(qi.Text.Replace("\r\n", "")));
this.Document.Blocks.Add(itemParagraph);
string analysis = qi.AnalysisText.Replace("\r\n", "");
if (string.IsNullOrEmpty(analysis) == false)
{
Paragraph itemAnalisys = new Paragraph() { Foreground = Brushes.Transparent, TextIndent = 30, };
choiceItemTextBlock.Tag = itemAnalisys;
choiceItemTextBlock.MouseLeftButtonDown += numTextBlock_MouseLeftButtonDown;
choiceItemTextBlock.Background = Brushes.Gray;
choiceItemTextBlock.Foreground = Brushes.White;
itemAnalisys.Inlines.Add(new Run(analysis));
//this.Document.Blocks.Add(itemAnalisys);//改成单击选项标头时插入,这样可以在一开始就看到所有选项,而不是空缺大段空白。
}
if (qi.IsAnswer) answerHeaderText = choiceItemHeaderText.Replace(".", "");
}
tbTitle.Text = this.Title = "试题演示(" + (this.point + 1).ToString() + " ∕ " + this.questions.Count.ToString() + ")";
Paragraph answerParagraph = new Paragraph();
answerTextBlock = new TextBlock()
{
Text = "?",//问号,在Wingdings字体中是一手执笔的形象。
ToolTip = "按F1或?显示",
FontFamily = new System.Windows.Media.FontFamily("Wingdings"),
FontWeight = FontWeights.Bold,
Padding = new Thickness(12, 0, 10, 0),
Margin = new Thickness(0, 0, 10, 0),
Foreground = Brushes.White,
Background = Brushes.Red,
};
answerTextBlock.MouseLeftButtonDown += answerTextBlock_MouseLeftButtonDown;
answerParagraph.Inlines.Add(answerTextBlock);
var answerRun = new Run(" " + answerHeaderText + " " + answerText)
{
Foreground = Brushes.Transparent,
FontWeight = FontWeights.Bold,
};
answerTextBlock.Tag = answerRun;
answerParagraph.Inlines.Add(answerRun);
this.Document.Blocks.Add(answerParagraph);
}
void answerTextBlock_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
this.ShowChoiceQuestionAnswer(this.answerTextBlock);
}
private void ShowChoiceQuestionAnswer(TextBlock answerTextBlock)
{
if (answerTextBlock == null) return;
var answerRun = answerTextBlock.Tag as Run;
if (answerRun == null) return;
if (answerRun.Foreground == Brushes.Transparent)
{
answerRun.Foreground = Brushes.Red;
if (this.answerRun != null)
this.answerRun.Foreground = Brushes.Red;
this.answerVisible = true;
}
else
{
answerRun.Foreground = Brushes.Transparent;
if (this.answerRun != null)
this.answerRun.Foreground = Brushes.Transparent;
this.answerVisible = false;
}
}
void numTextBlock_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
var textBlock = sender as TextBlock;
if (textBlock == null || textBlock.Tag == null) return;
ShowAnalysys(textBlock);
}
private void ShowAnalysys(TextBlock textBlock)
{
var paragraph = textBlock.Tag as Paragraph;
if (paragraph == null) return;//有些选项没有解析。
if (this.Document.Blocks.Contains(paragraph) == false)
{
this.Document.Blocks.InsertAfter((textBlock.Parent as InlineUIContainer).Parent as Paragraph, paragraph);
textBlock.Background = Brushes.Transparent;
textBlock.Foreground = Brushes.DarkBlue;
}
else
{
this.Document.Blocks.Remove(paragraph);
textBlock.Background = Brushes.Gray;
textBlock.Foreground = Brushes.White;
}
if (paragraph.Foreground != Brushes.Transparent)
{
paragraph.Foreground = Brushes.Transparent;
}
else
{
paragraph.Foreground = Brushes.Blue;
}
}
private void btnNext_Click(object sender, RoutedEventArgs e)
{
if (this.point < this.questions.Count - 1)
{
this.point++;
this.ShowQuestion();
}
else
{
LMessageBox.Show("已至最后一题!", Globals.AppName, MessageBoxButton.OK, MessageBoxImage.Warning, "", null, this);
}
}
private void btnPreview_Click(object sender, RoutedEventArgs e)
{
if (this.point > 0)
{
this.point--;
this.ShowQuestion();
}
else
{
LMessageBox.Show("已至第一题!", Globals.AppName, MessageBoxButton.OK, MessageBoxImage.Warning, "", null, this);
}
}
private void Window_PreviewKeyDown(object sender, KeyEventArgs e)
{
KeyStates ksLeftCtrl = Keyboard.GetKeyStates(Key.LeftCtrl);
KeyStates ksRightCtrl = Keyboard.GetKeyStates(Key.RightCtrl);
KeyStates ksLeftShift = Keyboard.GetKeyStates(Key.LeftShift);
KeyStates ksRightShift = Keyboard.GetKeyStates(Key.RightShift);
KeyStates ksLeftAlt = Keyboard.GetKeyStates(Key.LeftAlt);
KeyStates ksRightAlt = Keyboard.GetKeyStates(Key.RightAlt);
KeyStates ksLeftWin = Keyboard.GetKeyStates(Key.LWin);
KeyStates ksRightWin = Keyboard.GetKeyStates(Key.RWin);
bool isCtrl = ((ksLeftCtrl & KeyStates.Down) > 0 || (ksRightCtrl & KeyStates.Down) > 0);
//bool isShift = ((ksLeftShift & KeyStates.Down) > 0 || (ksRightShift & KeyStates.Down) > 0);
//bool isAlt = ((ksLeftAlt & KeyStates.Down) > 0 || (ksRightAlt & KeyStates.Down) > 0);
//bool isWin = ((ksLeftWin & KeyStates.Down) > 0 || (ksRightWin & KeyStates.Down) > 0);
if ((e.Key >= Key.A && e.Key <= Key.Z))
{
string alpha = L.GetAlpha(e.Key);
for (int i = this.Document.Blocks.Count - 1; i >= 0; i--)
{
var block = this.Document.Blocks.ElementAt(i);
var paragraph = block as Paragraph;
if (paragraph == null || paragraph.Inlines.Count <= 0) continue;
var uicontainer = paragraph.Inlines.FirstInline as InlineUIContainer;
if (uicontainer == null) continue;
var textBlock = uicontainer.Child as TextBlock;
if (textBlock == null || textBlock.Text.StartsWith(alpha) == false) continue;
ShowAnalysys(textBlock);
break;
}
}
//数字键1到9,表示选择学生名册中第几批次(可以将一个班级分为几批)
if (e.Key >= Key.D1 && e.Key <= Key.D9)
{
int index = e.Key - Key.D1;
if (index < 0) index = 0;
if (index > cmboxStudentsListFilenames.Items.Count - 1) index = cmboxStudentsListFilenames.Items.Count - 1;
if (index >= 0 && index <= cmboxStudentsListFilenames.Items.Count - 1)
{
cmboxStudentsListFilenames.SelectedIndex = index;
}
//如果索引越界,不起任何作用。
}
if (e.Key == Key.F1 || e.Key == Key.OemQuestion)
{
//这段是老代码,在新增加的“填空模式”下无法工作,而“答案”按钮可以正常工作。故去除之。
//显示答案
//string alpha = "?";
//for (int i = this.Document.Blocks.Count - 1; i >= 0; i--)
//{
// var block = this.Document.Blocks.ElementAt(i);
// var paragraph = block as Paragraph;
// if (paragraph == null || paragraph.Inlines.Count <= 0) continue;
// var uicontainer = paragraph.Inlines.FirstInline as InlineUIContainer;
// if (uicontainer == null) continue;
// var textBlock = uicontainer.Child as TextBlock;
// if (textBlock == null || textBlock.Text.StartsWith(alpha) == false) continue;
// ShowAnswer(textBlock);
// break;
//}
btnShowAnswer_Click(sender, e);
}
//if (isCtrl)
//{
//这三个快捷键是控件自带的。
//if (e.Key == Key.OemMinus)
//{
// if (this.Document.FontSize > 12)
// {
// this.Document.FontSize -= 2;
// }
//}
//if (e.Key == Key.OemPlus)
//{
// if (this.Document.FontSize < 98)
// {
// this.Document.FontSize += 2;
// }
//}
//if (e.Key == Key.D0)
//{
// this.Document.FontSize = 20;
//}
//}
if (!isCtrl)
{
if (e.Key == Key.OemComma || e.Key == Key.OemOpenBrackets || e.Key == Key.OemMinus || e.Key == Key.Prior)//Prior,即PageUp
{
if (this.point > 0)
{
this.point--;
this.ShowQuestion();
}
else
{
LMessageBox.Show("已至第一题!", Globals.AppName, MessageBoxButton.OK, MessageBoxImage.Warning, "", null, this);
}
e.Handled = true;
}
if (e.Key == Key.OemPeriod || e.Key == Key.OemCloseBrackets || e.Key == Key.OemPlus || e.Key == Key.Next)//句号。Key.Next即Key.PageDown。
{
if (this.AnswerVisible)
{
if (this.point < this.questions.Count - 1)
{
this.point++;
this.ShowQuestion();
}
else
{
LMessageBox.Show("已至最后一题!", Globals.AppName, MessageBoxButton.OK, MessageBoxImage.Warning, "", null, this);
}
}
else
{
ShowAnswer();
}
e.Handled = true;
}
if (e.Key == Key.Escape)//因为理论上选项可能用到X,所以不能用X键来退出。
{
if (this.askPanel.Visibility == Visibility.Visible)
{
this.askPanel.Visibility = Visibility.Collapsed;//隐藏提问面板。
e.Handled = true;
return;
}
this.Close();
}
//Tab键用于提问。
if (e.Key == Key.Tab)
{
AskSomeoneAQuestion();
e.Handled = true;
}
//Enter键用于显示答案。显示答案按钮设置为IsDefault即可
//if (e.Key == Key.Enter)
//{
// btnShowAnswer_Click(sender, e);
// e.Handled = true;
//}
}
}
private void btnExportQuestions_Click(object sender, RoutedEventArgs e)
{
this.Hide();
if (this.questions.Count <= 0)
{
this.Document.Blocks.Add(new Paragraph(new Run("文档中没有任何可以提取的试题!")));
this.Document.Focus();
return;
}
StringBuilder sbQuestion = new StringBuilder();
StringBuilder sbAnalysysAndAnswer = new StringBuilder();//answer专门添加而不是每题添加
for (int indexOfQuestion = 0; indexOfQuestion < this.questions.Count; indexOfQuestion++)
{
var q = this.questions[indexOfQuestion];
switch (q.Type)
{
case QuestionType.Choice:
case QuestionType.Judge:
{
//带一对方括弧的是填充项。
string title = q.TitleString;
//根据title生成段落。
int startBracket, endBracket;
startBracket = title.IndexOf("【");
endBracket = title.IndexOf("】");
if (startBracket < 0 || endBracket < 0) break;
//题号
sbQuestion.Append((indexOfQuestion + 1).ToString() + ".");
sbAnalysysAndAnswer.Append((indexOfQuestion + 1).ToString() + ".");
string titleText = title.Substring(0, startBracket) + "( )" + title.Substring(endBracket + 1);
if (titleText.EndsWith("\r\n") == false) titleText += "\r\n";
sbQuestion.Append(titleText);
//添加各选项
//先需要混淆下顺序,否则会总选A了。
int[] randomArray = L.GetRandomIntArray(q.ChoiceItems.Count);
for (int i = 0; i < randomArray.Length; i++)
{
var qi = q.ChoiceItems[i];
qi.OrderNumber = randomArray[i];
}
q.ChoiceItems.Sort(new CmparsionQuestionItem());
string answerHeaderText = "未设置答案项";
for (int i = 0; i < q.ChoiceItems.Count; i++)
{
ChoiceItem qi = q.ChoiceItems[i];
string choiceItemHeaderText = L.ConvertToAlpha(i + 1);
sbQuestion.Append(choiceItemHeaderText);
sbQuestion.Append(qi.Text.Replace("\r\n", ""));
sbQuestion.Append("\r\n");
string analysis = qi.AnalysisText.Replace("\r\n", "");
if (qi.IsAnswer) answerHeaderText = choiceItemHeaderText.Replace(".", "");
sbAnalysysAndAnswer.Append(choiceItemHeaderText);
sbAnalysysAndAnswer.Append(string.IsNullOrEmpty(analysis) ? "<此项未提供解析>" : analysis);
sbAnalysysAndAnswer.Append("\r\n");
}
sbQuestion.Append("\r\n\r\n");//每题之间空一行。
sbAnalysysAndAnswer.Append("----------\r\n【答案】" + answerHeaderText + "。\r\n\r\n");
break;
}
case QuestionType.FillBlank:
{
string answerHeaderText = "";
string title = q.TitleString;
int previewStartBacket = -1; int previewEndBracket = -1;
int startBracket, endBracket;
startBracket = title.IndexOf("【");
endBracket = title.IndexOf("】");
if (startBracket < 0 || endBracket < 0) break;
//题号
sbQuestion.Append((indexOfQuestion + 1).ToString() + ".");
sbAnalysysAndAnswer.Append((indexOfQuestion + 1).ToString() + ".");
int answerPieceNumber = 1;
while (startBracket >= 0 && endBracket >= 0)
{
sbQuestion.Append(title.Substring(previewEndBracket + 1, startBracket - previewEndBracket - 1));
string answerPiece = title.Substring(startBracket + 1, endBracket - startBracket - 1);
sbQuestion.Append(ReplaceWithUnderLine(answerPiece));
answerHeaderText += "[" + answerPieceNumber.ToString() + "]" + answerPiece + " ";
previewEndBracket = endBracket;
previewStartBacket = startBracket;
startBracket = title.IndexOf("【", endBracket + 1);
endBracket = title.IndexOf("】", endBracket + 1);
answerPieceNumber++;
}
sbQuestion.Append(title.Substring(previewEndBracket + 1) + "\r\n");
sbAnalysysAndAnswer.Append("【答案】" + answerHeaderText.Substring(0, answerHeaderText.Length - 1) + "。\r\n\r\n");
break;
}
case QuestionType.Subjective:
{
string title = q.TitleString.Replace("\r\n", "");
if (string.IsNullOrEmpty(title))
{
title = "阅读下列材料:";
}
//根据title生成段落。
sbQuestion.Append((indexOfQuestion + 1).ToString() + ".");
sbQuestion.Append(title);
//材料部分。
foreach (var s in q.Materials)
{
int indexOfcc = s.IndexOf("<<出处>>");
if (indexOfcc >= 0)
{
sbQuestion.Append(s.Substring(0, indexOfcc).Replace("\r\n", "") + "\r\n");
string clcc = s.Substring(indexOfcc + 6);
if (clcc.StartsWith("——") == false)
{
clcc = "——" + clcc;
}
sbQuestion.Append(clcc + "\r\n");
}
else
{
sbQuestion.Append(s.Replace("\r\n", "") + "\r\n");
}
}
sbQuestion.Append("请回答:\r\n");
//问题部分
for (int i = 0; i < q.AsksList.Count; i++)
{
var s = q.AsksList[i];
sbQuestion.Append("(" + (i + 1).ToString() + ")" + s.Replace("\r\n", "") + "\r\n");
}
sbQuestion.Append("\r\n");
//下面是答案部分。
sbAnalysysAndAnswer.Append((indexOfQuestion + 1) + ".");
for (int i = 0; i < q.Answers.Count; i++)
{
var s = q.Answers[i];
int indexOfjx = s.IndexOf("解析>>");
if (indexOfjx >= 0)
{
sbAnalysysAndAnswer.Append("(" + (i + 1).ToString() + ")" + s.Substring(0, indexOfjx).Replace("\r\n", ""));
sbAnalysysAndAnswer.Append(s.Substring(indexOfjx + 6));
}
else
{
sbAnalysysAndAnswer.Append("(" + (i + 1).ToString() + ")" + s.Replace("\r\n", ""));
}
}
sbAnalysysAndAnswer.Append("\r\n\r\n");
break;
}
}
}
Clipboard.SetData(DataFormats.Text, sbQuestion.ToString() + sbAnalysysAndAnswer.ToString());
LMessageBox.Show("此文档所有试题均已复制到剪贴板!", Globals.AppName, MessageBoxButton.OK, MessageBoxImage.Information, "", null, this);
this.Close();//便于操作。
}
private static string ReplaceWithUnderLine(string src)
{
if (string.IsNullOrEmpty(src)) return string.Empty;
var sb = new StringBuilder();
for (int i = 0; i <= src.Length; i++)//多加一对半角下划线字符。
{
sb.Append("__");
}
return sb.ToString();
}
private void btnShowAnswer_Click(object sender, RoutedEventArgs e)
{
ShowAnswer();
}
private void ShowAnswer()
{
//如果正在提问,隐藏提问面板
if (askPanel.Visibility != System.Windows.Visibility.Collapsed)
{
askPanel.Visibility = System.Windows.Visibility.Collapsed;
}
if (this.point < 0 || this.point >= this.questions.Count) return;
//this.answerVisible = true | false;//这个值由具体的ShowXXXAnswer()方法决定。
switch (this.questions[this.point].Type)
{
case QuestionType.Judge://判断题是特殊的选择题。
case QuestionType.Choice:
{
this.ShowChoiceQuestionAnswer(this.answerTextBlock);
break;
}
case QuestionType.FillBlank:
{
this.ShowFillBlankQuestionAnswer(this.answerTextBlock);
break;
}
case QuestionType.Subjective:
{
this.ShowSubjectiveQuestionAnswer(this.answerTextBlock);
break;
}
}
this.Document.Focus();
}
private void ShowSubjectiveQuestionAnswer(TextBlock textBlock)
{
if (this.answerParagraph == null) return;
if (this.Document.Blocks.Contains(this.answerParagraph))
{
// 已处于显示答案状态,隐藏答案
if (this.Document.Blocks.Contains(this.answerParagraph))
{
this.Document.Blocks.Remove(this.answerParagraph);
}
for (int i = this.answerParagraphList.Count - 1; i >= 0; i--)
{
if (this.Document.Blocks.Contains(this.answerParagraphList[i]))
this.Document.Blocks.Remove(this.answerParagraphList[i]);
}
this.answerVisible = false;
}
else
{
if (this.Document.Blocks.Contains(this.answerParagraph) == false)
{
this.Document.Blocks.Add(this.answerParagraph);
}
foreach (var p in this.answerParagraphList)
{
if (this.Document.Blocks.Contains(p) == false)
this.Document.Blocks.Add(p);
}
this.answerVisible = true;
}
ScrollViewer scrollViewer = GetScrollViewer(mainDocumentReader) as ScrollViewer;
if (scrollViewer != null)
{
scrollViewer.ScrollToEnd();
}
}
public static DependencyObject GetScrollViewer(DependencyObject o)
{
// Return the DependencyObject if it is a ScrollViewer
if (o is ScrollViewer)
{ return o; }
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(o); i++)
{
var child = VisualTreeHelper.GetChild(o, i);
var result = GetScrollViewer(child);
if (result == null)
{
continue;
}
else
{
return result;
}
}
return null;
}
private void ShowFillBlankQuestionAnswer(TextBlock textBlock)
{
foreach (var block in this.Document.Blocks)
{
var paragraph = block as Paragraph;
if (paragraph == null) continue;
foreach (var inline in paragraph.Inlines)
{
var span = inline as Span;
if (span == null) continue;
if (span.Tag.ToString() == "FillBlank")
{
foreach (var run in span.Inlines)
{
var answerRun = run as Run;
if (answerRun == null) continue;
if (answerRun.Foreground == Brushes.Transparent)
{
answerRun.Foreground = Brushes.Red;
if (answerVisible != true)
{
answerVisible = true;
}
}
else
{
answerRun.Foreground = Brushes.Transparent;
if (answerVisible != false)
{
answerVisible = false;
}
}
}
}
}
}
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
#region 载入学生名册列表
try
{
cmboxStudentsListFilenames.Items.Clear();
string studentListDirectoryPath = Globals.PathOfUserFolder + (Globals.PathOfUserFolder.EndsWith("\\") ? "" : "\\") + "StudentsLists\\";
if (Directory.Exists(studentListDirectoryPath) == false)
{
Directory.CreateDirectory(studentListDirectoryPath);
}
DirectoryInfo studentListDirectoryinfo = new DirectoryInfo(studentListDirectoryPath);
FileInfo[] childFiles = studentListDirectoryinfo.GetFiles();
if (childFiles.Count<FileInfo>() <= 0)
{
var sampleClassFilePath = studentListDirectoryPath + "SampleClass.txt";
if (File.Exists(sampleClassFilePath) == false)
{
File.WriteAllText(sampleClassFilePath, Properties.Resources.SampleClassFileContent);
}
}
var directoryInfo = new DirectoryInfo(studentListDirectoryPath);
var fileInfos = directoryInfo.GetFiles();
foreach (var fi in fileInfos)
{
cmboxStudentsListFilenames.Items.Add(new ComboBoxItem() { Content = fi.Name, });
}
var selectedStudentListShortFileName = App.ConfigManager.Get("SelectedStudentListShortFileName");
if (selectedStudentListShortFileName != null && selectedStudentListShortFileName != string.Empty)
{
ComboBoxItem cbi = null;
foreach (var i in cmboxStudentsListFilenames.Items)
{
var ii = i as ComboBoxItem;
if (ii == null) continue;
if (ii.Content.ToString() == selectedStudentListShortFileName)
{
cbi = ii;
break;
}
}
if (cbi != null)
{
var newIndex = cmboxStudentsListFilenames.Items.IndexOf(cbi);
cmboxStudentsListFilenames.SelectedIndex = newIndex;
}
else
{
if (cmboxStudentsListFilenames.Items.Count > 0)
{
cmboxStudentsListFilenames.SelectedIndex = 0;
}
}
}
else
{
if (cmboxStudentsListFilenames.Items.Count > 0)
{
cmboxStudentsListFilenames.SelectedIndex = 0;
}
}
}
catch (Exception ex)
{
LMessageBox.Show(ex.Message, Globals.AppName, MessageBoxButton.OK, MessageBoxImage.None, "", null, this);
}
#endregion 载入学生名册
//载入缩放比例
string zoomText = App.ConfigManager.Get("Zoom");
if (string.IsNullOrEmpty(zoomText) == false)
{
try
{
double zoom = double.Parse(zoomText);
mainDocumentReader.Zoom = zoom;
}
catch (Exception)
{
mainDocumentReader.Zoom = 150;
}
}
//载入填空题演示模式
string fillBlankMode = App.ConfigManager.Get("MultiFillBlankMode");
if (string.IsNullOrEmpty(fillBlankMode) == false)
{
if (fillBlankMode == true.ToString())
{
cmboxFillBlankView.SelectedIndex = 0;//源填空题中有几个填空项,仍作一题显示。
}
else
{
cmboxFillBlankView.SelectedIndex = 1;//每填空项拆分成一道填空题,且乱序排列。
}
}
Globals.SwitchInputMethod(false);
this.Document.Focus();
}
private void Window_Activated(object sender, EventArgs e)
{
Globals.SwitchInputMethod(false);
this.Document.Focus();
}
private void cmboxFillBlankView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
this.BuildQuestions(ContentText);
}
public string ContentText { get; set; }
//如果在演示主观题,滚轮去除滚动、PageDown/PageUp又去除功能,还怎么滚动呢?
//private void FlowDocumentReader_PreviewMouseWheel(object sender, MouseWheelEventArgs e)
//{
// if (e.Delta < 0)
// {
// btnNext_Click(sender, e);
// }
// else
// {
// btnPreview_Click(sender, e);
// }
// e.Handled = true;
//}
private void AskSomeoneAQuestion()
{
var student = this.GetAStudent();
if (student == null)
{
tbkStudentName.Text = "<未设置名册>";
}
else
{
tbkStudentName.Text = student.Number + "号 " + student.Name;
}
askPanel.Visibility = System.Windows.Visibility.Visible;
}
private void btnAskRandom_Click(object sender, RoutedEventArgs e)
{
this.AskSomeoneAQuestion();
}
private void cmboxStudentsListFilenames_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var selItem = cmboxStudentsListFilenames.SelectedItem as ComboBoxItem;
if (selItem == null) return;
string fileShortName = selItem.Content as string;
if (string.IsNullOrEmpty(fileShortName)) return;
ReadStudentsFromFile(fileShortName);
}
private List<Student> students;
private void ReadStudentsFromFile(string fileShortName)
{
if (students == null)
{
students = new List<Student>();
}
students.Clear();
if (string.IsNullOrEmpty(fileShortName))
{
return;
}
//先看文件在何处。
string studentListFileFullPath = Globals.PathOfUserFolder + (Globals.PathOfUserFolder.EndsWith("\\") ? "" : "\\") + "StudentsLists\\" + fileShortName;
if (File.Exists(studentListFileFullPath))
{
using (StreamReader sr = new StreamReader(studentListFileFullPath))
{
while (!sr.EndOfStream) //读到结尾退出
{
string strLine = sr.ReadLine(); strLine = strLine.Trim();
if (strLine.Length == 0) continue;
if (strLine.StartsWith("//")) continue;//这个用作备注。
if (strLine.Contains("//"))
{
strLine = strLine.Substring(0, strLine.IndexOf("//"));
}
if (string.IsNullOrEmpty(strLine)) continue;
//将每一行拆分,分隔符就是char 数组中的字符
string[] stringPieces = strLine.Split(new char[] { '\t', ' ', ',' }, StringSplitOptions.RemoveEmptyEntries);
//将拆分好的string[] 存入list
if (stringPieces.Length == 2)
{
students.Add(new Student() { Name = stringPieces[1], Number = stringPieces[0], });
}
}
}
}
RandomStudents();
}
private void RandomStudents()
{
if (studentPoint >= students.Count)
{
studentPoint = 0;
}
//混淆。
int[] random = L.GetRandomIntArray(students.Count);
foreach (int i in random)
{
students[i].OrderNumber = random[i];
}
students.Sort(new CmparsionStudent());
}
private int studentPoint = 0;
private Student GetAStudent()
{
if (students == null || students.Count <= 0) return null;
var student = students[studentPoint];
studentPoint++;
//重新混淆一次。
if (studentPoint >= students.Count)
{
RandomStudents();
studentPoint = 0;
}
return student;
}
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
this.Hide();
//在配置文件在存储缩放比例。
App.ConfigManager.Set("Zoom", mainDocumentReader.Zoom.ToString());
//在配置文件中存储当前使用的学生名册
if (cmboxStudentsListFilenames.SelectedItem != null)
{
var cbi = cmboxStudentsListFilenames.SelectedItem as ComboBoxItem;
if (cbi != null)
{
App.ConfigManager.Set("SelectedStudentListShortFileName", cbi.Content.ToString());
}
}
//在配置文件中保存“填空题显示模式”
if (cmboxFillBlankView.SelectedIndex == 0)
{
App.ConfigManager.Set("MultiFillBlankMode", true.ToString());
}
else if (cmboxFillBlankView.SelectedIndex == 1)
{
App.ConfigManager.Set("MultiFillBlankMode", false.ToString());
}
e.Cancel = true;
}
private System.Windows.Threading.DispatcherTimer timer = new System.Windows.Threading.DispatcherTimer();
private void tbTime_Loaded(object sender, RoutedEventArgs e)
{
timer = new System.Windows.Threading.DispatcherTimer();
timer.Interval = new TimeSpan(0, 1, 0); //间隔1秒
timer.Tick += Timer_Tick;
timer.Start();
}
private void Timer_Tick(object sender, EventArgs e)
{
tbTime.Text = DateTime.Now.ToLongTimeString();
}
}
class CmparsionQuestionItem : IComparer<ChoiceItem>
{
public int Compare(ChoiceItem x, ChoiceItem y)
{
return x.OrderNumber.CompareTo(y.OrderNumber);
}
}
class CmparsionQuestion : IComparer<Question>
{
public int Compare(Question x, Question y)
{
return x.OrderNumber.CompareTo(y.OrderNumber);
}
}
public class Student
{
private string number = string.Empty;
public string Number
{
get
{
return this.number;
}
set { this.number = value; }
}
private string name = "无名氏";
public string Name
{
get { return this.name; }
set { this.name = value; }
}
public int OrderNumber { get; set; }
}
class CmparsionStudent : IComparer<Student>
{
public int Compare(Student x, Student y)
{
return x.OrderNumber.CompareTo(y.OrderNumber);
}
}
}
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Комментарий ( 0 )