WPF C#实现用户输入驱动的彩票文件批量生成需求及代码调整
解决WPF C#批量生成彩票文件的问题
问题需求
实现从TextBox获取1-10的数字输入,根据输入数量批量生成对应彩票文件,文件名格式为LottoKupon1.txt、LottoKupon2.txt等。现有代码尝试用for循环实现批量生成但未成功,以下是修改方案。
现有代码问题分析
FolderCreater类的固定fileName字段无法生成带编号的文件Lotto方法未接收动态参数,无法适配不同文件名- 按钮点击事件未读取TextBox输入,也未实现循环批量调用逻辑
- 全局
ListOfAllArrays会累积跨批次数据,导致重复行检查逻辑出错 - 每次调用
Lotto时重新实例化Random,可能因时间戳相同生成重复随机数
修改后完整代码
1. 文件夹创建类FolderCreater修改
namespace Lottery { internal class FolderCreater { private static readonly string folderName = @"C:\lotto"; public static void CreateFolder() { if (!Directory.Exists(folderName)) { Directory.CreateDirectory(folderName); } } // 根据编号生成带序号的文件名 public static string GetFileName(int fileNumber) { return Path.Combine(folderName, $"LottoKupon{fileNumber}.txt"); } } }
2. 主窗口类MainWindow修改
namespace Lottery { public partial class MainWindow : Window { // 全局Random实例,避免短时间内重复生成相同随机数 private readonly Random randNum = new Random(); public MainWindow() { InitializeComponent(); } // 接收文件编号参数,动态生成对应彩票文件 public void Lotto(int fileNumber) { string fileName = FolderCreater.GetFileName(fileNumber); // 使用using自动释放StreamWriter资源 using (StreamWriter sw = new StreamWriter(fileName)) { sw.WriteLine(" " + "Lotto " + DateTime.Now.ToString("dd/MM/yyyy\n")); sw.WriteLine(" " + "1-uge\n" + " LYN-LOTTO\n"); int[][] allArrays = new int[10][]; for (int i = 0; i < 10; i++) { allArrays[i] = new int[7]; } int rowNr = 0; foreach (int[] row in allArrays) { rowNr++; sw.Write(rowNr + ". "); // 生成当前行的不重复随机数 for (int j = 0; j < 7; j++) { int number = randNum.Next(1, 37); while (row.Any(n => n == number)) { number = randNum.Next(1, 37); } row[j] = number; } Array.Sort(row); // 格式化输出两位数字 for (int l = 0; l < 7; l++) { sw.Write(row[l].ToString("00") + " "); } sw.Write("\n"); } // 检查当前彩票是否有重复行,有则重新生成 if (HasDuplicateRows(allArrays)) { sw.Close(); File.Delete(fileName); Lotto(fileNumber); return; } // 处理Joker Tal复选框逻辑 if (CheckBox.IsChecked == true) { sw.WriteLine("\n****** Joker Tal ******"); int[][] allJokerRows = new int[2][]; for (int i = 0; i < 2; i++) { allJokerRows[i] = new int[7]; } foreach (int[] n in allJokerRows) { sw.Write(" "); for (int i = 0; i < 7; i++) { n[i] = randNum.Next(1, 10); } Array.Sort(n); for (int u = 0; u < 7; u++) { sw.Write(n[u] + " "); } sw.Write("\n"); } } // 将生成的文件路径添加到ListBox显示 ListBox.Items.Add($"已生成:{fileName}"); } } // 检查当前彩票是否存在重复行 private bool HasDuplicateRows(int[][] allArrays) { HashSet<long> rowHashes = new HashSet<long>(); foreach (int[] row in allArrays) { long hash = MakeRowHash(row); if (!rowHashes.Add(hash)) { return true; } } return false; } // 将行数字转换为唯一哈希值(补零避免1和01混淆) private long MakeRowHash(int[] row) { string hashStr = string.Concat(row.Select(n => n.ToString("00"))); return Convert.ToInt64(hashStr); } private void cmdOk_Click_1(object sender, RoutedEventArgs e) { // 验证TextBox输入有效性 if (!int.TryParse(txtBox.Text.Trim(), out int generateCount) || generateCount < 1 || generateCount > 10) { MessageBox.Show("请输入1-10之间的有效数字!"); return; } FolderCreater.CreateFolder(); ListBox.Items.Clear(); // 循环生成对应数量的彩票文件 for (int i = 1; i <= generateCount; i++) { Lotto(i); } MessageBox.Show($"已成功生成{generateCount}个彩票文件!"); } } }
核心修改说明
- 动态文件名生成:
FolderCreater新增GetFileName方法,根据输入编号生成对应文件名,避免固定文件名覆盖问题 - 批量生成逻辑:按钮点击事件中读取并验证TextBox输入,通过for循环调用
Lotto方法生成对应数量的文件 - 重复行检查优化:将重复行检查改为局部逻辑,使用
HashSet存储行哈希值,避免全局数据污染,同时补零生成哈希值防止数字混淆 - 资源管理优化:使用
using语句自动释放StreamWriter资源,避免文件占用问题 - 随机数稳定性:使用全局
Random实例,避免短时间内多次实例化导致的随机数重复问题 - 用户体验提升:添加输入验证和ListBox文件路径显示,明确反馈生成结果
内容的提问来源于stack exchange,提问作者someone
相关产品推荐
相关产品推荐

