Распределение класса по нескольким файлам и создание вспомогательных функций
Код решения поставленной задачи будет достаточно большим. Чтобы сделать его обозримым, распределим отдельные группы частичного класса по отдельным файлам в соответствии с разделами меню. Все равно компилятор их увидет и соберет в единую сборку.
- В панели Solution Explorer выделите узел проекта Notepad1 и командой Project/Add Class добавьте три файла с именами File.cs, Edit.cs и Other.cs
- Скопируйте из файла Window1.xaml.cs в каждый из этих новых файлов код подключения пространств имен и отредактируйте заготовки частей класса Window1, которые пока будут одинаковые, так
using System;using System.Collections.Generic;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.Navigation;using System.Windows.Shapes; namespace Notepad1{ partial class Window1 { }} - Откройте файл Window1.xaml.cs и дополните класс Window1 вспомогательным кодом, после чего он должен стать таким
using System;using System.Windows;using System.Windows.Input; using Microsoft.Win32; // Для стандартных диалогов Win32using System.IO; // Работа с файлами и каталогами namespace Notepad1{ public partial class Window1 : Window { public Window1() { InitializeComponent(); } private void Window_Loaded(object sender, RoutedEventArgs e) { // Отключаем в TextBox встроенный жест Ctrl+X для команды Cut KeyBinding keyBinding = new KeyBinding( ApplicationCommands.NotACommand, Key.X, ModifierKeys.Control); txtBox1.InputBindings.Add(keyBinding); // Отключаем в TextBox встроенный жест Ctrl+C для команды Copy keyBinding = new KeyBinding( ApplicationCommands.NotACommand, Key.C, ModifierKeys.Control); txtBox1.InputBindings.Add(keyBinding); // Отключаем в TextBox встроенный жест Ctrl+V для команды Paste keyBinding = new KeyBinding( ApplicationCommands.NotACommand, Key.V, ModifierKeys.Control); txtBox1.InputBindings.Add(keyBinding); } #region private Fields - локальные поля //------------------------------------------------------ // // private Fields - локальные поля // //------------------------------------------------------ bool IsModified = false;// Флаг изменений содержимого string strLoadedFile; // Полное имя загруженного документа #endregion private Fields #region Auxiliary Methods - вспомогательные методы //------------------------------------------------------ // // Auxiliary Methods - вспомогательные методы // //------------------------------------------------------ // Метод возвращает true, если содержимое // TextBox не требует сохранения bool flag; bool CheckModifiedAndSaveIt() { if (!IsModified) return true; MessageBoxResult result = MessageBox.Show( "Сохранить изменения?", "", // Контекст и заголовок MessageBoxButton.YesNoCancel, // Кнопки диалога MessageBoxImage.Question, // Иконка вопроса MessageBoxResult.Yes // Кнопка с фокусом ); switch (result) { case MessageBoxResult.Yes: if (String.IsNullOrEmpty(strLoadedFile)) flag = DisplaySaveDialog(""); // Запись с диалогом else flag = SaveFile(strLoadedFile); // Просто запись break; case MessageBoxResult.No: flag = true; break; case MessageBoxResult.Cancel: flag = false; break; } return flag; } // Вызывает диалоговое окно записи файла // и возвращает true, если файл был сохранен bool DisplaySaveDialog(string strFileName) { SaveFileDialog dlg = new SaveFileDialog(); dlg.Filter = "Text Documents(*.txt)|*.txt|All Files(*.*)|*.*"; dlg.FileName = strFileName; bool result = (bool)dlg.ShowDialog(this); // Желание пользователя if (result) result = SaveFile(dlg.FileName); // Возможность компьютера return result; } // Сохраняет документ и возвращает true при успехе // Аргумент - полное имя файла bool SaveFile(string strFileName) { try { File.WriteAllText(strFileName, txtBox1.Text, System.Text.Encoding.GetEncoding(1251)); } catch (Exception e) { // Ловим все исключения и выводим диалог MessageBox.Show( "Ошибка записи файла:\n" + e.Message, "", MessageBoxButton.OK, MessageBoxImage.Asterisk ); return false; } strLoadedFile = strFileName; UpdateTitle(); // Меняем заголовок окна IsModified = false; // Нет изменений текста return true; } // Диалог открытия файла возвращает true при успехе bool DisplayOpenDialog() { flag = CheckModifiedAndSaveIt(); // Проверяем и сохраняем изменения if(!flag) return flag; OpenFileDialog dlg = new OpenFileDialog(); dlg.Filter = "Text Documents(*.txt)|*.txt|All Files(*.*)|*.*"; bool result = (bool)dlg.ShowDialog(this); // Желание пользователя if (result) result = OpenFile(dlg.FileName); // Возможность компьютера return result; } // Открывает файл и при успехе возвращает true bool OpenFile(string strFileName) { try { txtBox1.Text = File.ReadAllText(strFileName, System.Text.Encoding.GetEncoding(1251)); } catch (Exception e) { // Ловим все исключения и выводим диалог MessageBox.Show( "Ошибка чтения файла:\n" + e.Message, "", MessageBoxButton.OK, MessageBoxImage.Asterisk ); return false; } strLoadedFile = strFileName; UpdateTitle(); // Меняем заголовок окна IsModified = false; // Нет изменений текста // Сбрасываем границы выделенного текста поля редактирования txtBox1.SelectionStart = 0; txtBox1.SelectionLength = 0; return true; } // Коррекция заголовка окна void UpdateTitle() { // Извлекаем заголовок окна из словаря ресурсов String title = Application.Current. Resources["ApplicationTitle1"].ToString(); //if (strLoadedFile == null || strLoadedFile.Trim() == String.Empty) if (String.IsNullOrEmpty(strLoadedFile)) // Проще! { this.Title = "Untitled - " + title; return; } // Извлекаем имя файла из полного пути int startIndex = strLoadedFile.LastIndexOf('\\') + 1; int endIndex; // Проверяем в системном реестре настройки системы по скрытию расширения файлов using (RegistryKey filekey = Registry.CurrentUser.CreateSubKey( @"Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced")) { if ((filekey != null) && (filekey.GetValue("HideFileExt", 0).ToString() == "0")) { endIndex = strLoadedFile.Length; // Нет расширения } else { endIndex = strLoadedFile.LastIndexOf('.'); // Отсекаем расширение } } if (endIndex > startIndex) { this.Title = strLoadedFile.Substring(startIndex) + " - " + title; } else { this.Title = strLoadedFile.Substring(startIndex, endIndex - startIndex) + " - " + title; } } #endregion Auxiliary Methods }} Смысл добавленного кода подробно помечен коментариями и следует его внимательно изучить. Ключевым полем работы кода является флаг IsModified, сигнализирующий об изменении содержимого элемента TextBox. Поднятие флага выполним в обработчике события TextChanged этого элемента.
- В разметку TextBox добавьте регистрацию обработчика события TextChanged и создайте сам обработчик
<!-- Многострочное текстовое поле редактирования --> <TextBox TextWrapping="Wrap" AcceptsReturn="True" AcceptsTab="True" VerticalScrollBarVisibility="Auto" Name="txtBox1" TextChanged="txtBox1_TextChanged" > .................................................... </TextBox> - Обработчик txtBox1_TextChanged() заполните так
private void txtBox1_TextChanged(object sender, System.Windows.Controls.TextChangedEventArgs e) { if (IsModified) return; else IsModified = true; } Размещение вариантов заголовков окна в ресурсах приложения
В коде вспомогательных функций используется словарь ресурсов приложения, которые мы сейчас определим.
- Откройте файл разметки App.xaml и дополните его определением ресурсов для хранения неизменяемой части заголовка окна. Областью видимости этих ресурсов будет все приложение
<Application x:Class="Notepad1.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" StartupUri="Window1.xaml"> <Application.Resources> <String xmlns="clr-namespace:System;assembly=Mscorlib" x:Key="ApplicationTitle1"> Title="Window1: Управление состоянием источников команд" </String> <String xmlns="clr-namespace:System;assembly=Mscorlib" x:Key="ApplicationTitle2"> Title="Window2: Управление состоянием источников команд" </String> </Application.Resources></Application>
Дата добавления: 2015-04-15; просмотров: 865;