Опубликован: 05.08.2010 | Доступ: свободный | Студентов: 2008 / 45 | Оценка: 4.50 / 4.40 | Длительность: 60:26:00
Самостоятельная работа 10:

Текст WPF

Упражнение 6. Выборка текста из текстового файла с форматированием на лету

В данном упражнении приводится несколько примеров обработки текстовых файлов и их форматирования в FlowDocument программным способом. Мне надоело описывать пошаговые инструкции, а вам надоело их разбирать, поэтому приведу итоговый код для исследования.

Что я сделал?

  1. Добавил к решению новый проект типа WPF Application с именем WPFText6
  2. Создал в корне проекта каталог Documents и добавил в него готовый текстовый файл TextDocument.txt с таким случайным содержимым (приводится в каталоге Source )
    1. Критерием отнесения ТС к маршрутным является наличие установленного маршрута с обозначенными местами остановок. К таковым Правила относят автобусы, троллейбусы и трамваи (п. 1.2). Автомобили-такси к маршрутным ТС не относятся.
    2. Знак 4.1.4 "Движение прямо или направо" разрешает вам движение только прямо или поворот на АЗС, расположенную справа от дороги, т.е. в направлениях А или Б.
    3. Знак 5.7.1 "Выезд на дорогу с односторонним движением" информирует о направлении движения, установленном на пересекаемой дороге. Кроме поворота направо на этом перекрестке возможны движение прямо и разворот. При движении в любом из этих направлений вы должны уступить дорогу (знак 2.4 "Уступите дорогу") ТС, движущимся по пересекаемой дороге.
    4. Знак 5.29 "Зона регулируемой стоянки" относится к так называемым зональным знакам, требования которых действуют на всей территории (участке дороги), обозначенной такими знаками, вплоть до выезда из зоны, обозначенного в данном случае знаком 5.30 "Конец зоны регулируемой стоянки". Действие знаков не прерывается на перекрестках. При этом информацию о видах ТС, способах парковки и т.д. размещают на табличке под знаком или с помощью изображения таблички в нижней части знака. В данном случае табличка 8.6.2 "Способ постановки транспортного средства на стоянку" разрешает ставить легковые автомобили на стоянку с использованием тротуара на территории всей зоны регулируемой стоянки, т.е. на любой стороне дорог, расположенных в зоне регулируемой стоянки (Приложение 1).
    5. Разметка 1.19 (в виде стрел) предупреждает вас о необходимости покинуть полосу движения в связи с уменьшением количества полос в данном направлении (сужением проезжей части). Необходимо перестроиться на правую полосу.
    6. Для информирования водителей о предстоящей смене зеленого сигнала светофора на желтый Правилами предусмотрена возможность мигания зеленого сигнала. Этот сигнал разрешает движение ТС (п. 6.2). Длительность мигания при этом должна составлять 3 сек.
    7. Водитель обязан подавать сигналы световыми указателями поворота соответствующего направления перед началом движения, перестроением, поворотом, остановкой (п. 8.1). Двигаясь по закруглению дороги и не намереваясь перестраиваться или останавливаться, вы не должны включать указатели поворота, что бы не вводить в заблуждение других участников движения (п. 8.2).
    8. При взаимном перестроении водитель легкового автомобиля должен уступить дорогу водителю мотоцикла, находящемуся от него справа (п. 8.4).
    9. Выполняя разворот на этом перекрестке, вам придется использовать для движения участок проезжей части, имеющий двустороннее движение. Поэтому, въезжая на перекресток, вы можете продолжить движение только по правой стороне этого участка проезжей части (п. 1.4), т.е. по траектории А.
    10. Знак 4.6 "Ограничение минимальной скорости" и табличка 8.14 "Полоса движения" предписывают двигаться по левой полосе со скоростью не менее 50 км/ч. Однако при этом на дороге вне населенного пункта, не относящейся к автомагистрали, вы не имеете права развивать скорость на легковом автомобиле более 90 км/ч (п. 10.3).
    11. На нерегулируемых перекрестках обгон запрещен при движении по дороге, не являющейся главной (п. 11.5). Поскольку водитель легкового автомобиля приближается к перекрестку неравнозначных дорог, двигаясь по главной дороге (знак 2.3.1 "Пересечение с второстепенной дорогой"), то он может совершить обгон обоих грузовых автомобилей, так как дорога имеет две полосы для движения в данном направлении (п. 11.4). Следовательно, обгон может быть совершен по траекториям А и Б.
    12. Остановившись за пешеходным переходом в 5 м от края пересекаемой проезжей части и обеспечив при этом расстояние в 3 м до сплошной линии разметки, водитель не нарушил правила стоянки (пп. 12.4 и 12.5).
    13. При движении в направлении стрелки, включенной в дополнительной секции одновременно с красным сигналом светофора, вы обязаны уступать дорогу ТС, движущимся с других направлений (п. 13.5).
    14. Несмотря на то что легковой автомобиль первым въехал на перекресток равнозначных дорог, вы имеете перед ним преимущество, и его водитель при левом повороте должен уступить вам дорогу (пп. 13.11 и 13.12).
    15. Проезжая данный перекресток неравнозначных дорог по направлению главной дороги (знаки 2.1 "Главная дорога" и 8.13 "Направление главной дороги"), вы никому не должны уступать дорогу, так как пользуетесь преимуществом как перед находящимся на главной дороге автобусом, для которого вы являетесь "помехой справа" (пп. 13.10 и 13.11), так и перед легковым автомобилем, движущимся по второстепенной дороге (п. 13.9).
    16. Знак 5.21 "Жилая зона" показывает, что вы въезжаете на территорию, где скорость не должна превышать 20 км/ч (п. 10.2).
    17. При движении в темное время суток на неосвещенных участках дорог вы должны использовать, в зависимости от дорожных условий, скорости движения и наличия впереди встречных и попутных ТС, ближний или дальний свет фар (п. 19.1).
    18. Из всех перечисленных неисправностей только неработающий стеклоподъемник не является причиной запрещения эксплуатации вашего ТС. Остальные неисправности включены в Перечень (п. 7.4), и при их наличии эксплуатация ТС запрещена.
    19. При съезде автомобиля правыми колесами на неукрепленную и влажную обочину возникает опасность заноса из-за разницы сцепления правых и левых колес с дорогой. При этом целесообразно, не меняя скорости, т.е. не прибегая к торможению, плавным поворотом рулевого колеса вернуть автомобиль на проезжую часть. Торможение в данной ситуации может вызвать занос автомобиля.
    20. Раствор йода или бриллиантовой зелени вызывает химическое повреждение ткани внутри раны. Наружный слой кожи не повреждается при смазывании этими растворами, но эффективно дезинфицируется, что необходимо перед наложением марлевой повязки.

    Здесь знак подчеркивания '_' в начале параграфа является меткой для поиска в одном из примеров.

  3. Настроил свойства файла TextDocument.txt так
    • Build Action = None
    • Copy to Output Directory=Copy if newe
  4. Заполнил (последовательно, думая, соображая!) файл XAML так
    <Window x:Class="WpfText6.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Window1" 
        Height="300" 
        Width="300"
        MinHeight="300"
        MinWidth="300"
        ResizeMode="CanResizeWithGrip"
        Loaded="Window_Loaded"
            >
        <TabControl>
            
            <TabItem Header="OneParagraph">
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition />
                        <ColumnDefinition Width="50" />
                    </Grid.ColumnDefinitions>
                    <FlowDocumentScrollViewer 
                        DockPanel.Dock="Left"
                        x:Name="flowDocumentScrollViewer" 
                        ScrollViewer.VerticalScrollBarVisibility="Visible"
                        >
                        <FlowDocument Name="flowDoc" TextAlignment="Left" Background="White">
                            <Paragraph TextAlignment="Center" FontWeight="Bold" FontSize="21">
                                Чтение одного параграфа
                            </Paragraph>
                            <Paragraph Name="text" FontFamily="Arial" />
                        </FlowDocument>
                    </FlowDocumentScrollViewer>
                    <ListBox Grid.Column="1" Name="listBox" 
                        SelectionChanged="listBox_SelectionChanged" />
                </Grid>
            </TabItem>
            
            <TabItem Header="FullDocument">
                <FlowDocument Name="fullDocument" Loaded="fullDocument_Loaded" />
            </TabItem>
            
            <TabItem Header="SplitDocument">
                <FlowDocumentScrollViewer ScrollViewer.VerticalScrollBarVisibility="Auto">
                    <FlowDocument Name="splitDocument" 
                        Loaded="splitDocument_Loaded" Background="White" />
                </FlowDocumentScrollViewer>
            </TabItem>
        
            <TabItem Header="ListDocument">
                <FlowDocumentScrollViewer ScrollViewer.VerticalScrollBarVisibility="Auto">
                    <FlowDocument Name="listDocument" 
                        Initialized="listDocument_Initialized"  Background="White" />
                </FlowDocumentScrollViewer>
            </TabItem>
        </TabControl>
    </Window>
  5. Сочинил, думая!, кодовую часть так
    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;
        
    // Включаем дополнительные пространства имен
    using System.IO;
    using Microsoft.Win32;
    using System.Windows.Markup;
    using System.Collections;
        
    namespace WpfText6
    {
        public partial class Window1 : Window
        {
            public Window1()
            {
                InitializeComponent();
            }
        
            // Вынесли как поля для видимости в методах
            FileStream myStream;
            StreamReader myStreamReader;
            String[] arrayText;
            private void Window_Loaded(object sender, RoutedEventArgs e)
            {
                this.Background = Brushes.LightGray;
                // Можно вместо разделителя '\\' использовать '/' 
                String fileName = "Documents/TextDocument.txt";
        
                try
                {
                    myStream = new FileStream(fileName, FileMode.Open, FileAccess.Read);
                    myStreamReader = new StreamReader(myStream, Encoding.GetEncoding(1251));
        
                    // Не знаем, какой массив задать, поэтому читаем в коллекцию
                    // Но можно было и сразу в коллекцию StringBuilder.Append()
                    ArrayList arrayList = new ArrayList();
                    while (myStreamReader.EndOfStream != true)
                        arrayList.Add(myStreamReader.ReadLine());// Читаем построчно
        
                    // Копируем ссылки на элементы ArrayList в массив
                    arrayText = new String[arrayList.Count];
                    for (int i = 0; i < arrayList.Count; i++)
                        arrayText[i] = (String)arrayList[i];
        
                    // Заполняем ListBox
                    for (int i = 0; i < arrayText.Length; i++)
                    {
                        int pos = arrayText[i].IndexOf('.');
                        listBox.Items.Add(arrayText[i].Substring(0, pos + 1));
                    }
                    listBox.SelectedIndex = 0; // На первый элемент списка
                }
                catch { } // Один синтаксис!!!
                finally
                {
                    // Системные ресурсы надо закрывать
                    myStream.Close();
                    myStreamReader.Close();
                }
            }
        
            private void listBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
            {
                text.Inlines.Clear(); // Очищаем предыдущее содержимое
                text.Inlines.Add(arrayText[listBox.SelectedIndex]);// Добавляем новое
            }
        
            private void fullDocument_Loaded(object sender, RoutedEventArgs e)
            {
                fullDocument.Background = Brushes.White;// Фон документа программно
        
                for (int i = 0; i < arrayText.Length; i++)
                {
                    Paragraph para = new Paragraph();
                    para.FontFamily = new FontFamily("Arial");
                    para.Inlines.Add(arrayText[i]);
                    fullDocument.Blocks.Add(para);
                }
            }
        
            String[] textSplit;
            private void splitDocument_Loaded(object sender, RoutedEventArgs e)
            {
                // Можно вместо разделителя '\\' использовать '/' 
                String fileName = "Documents/TextDocument.txt";
        
                try
                {
                    myStream = new FileStream(fileName, FileMode.Open, FileAccess.Read);
                    myStreamReader = new StreamReader(myStream, Encoding.GetEncoding(1251));
    
                    String str = myStreamReader.ReadToEnd();// Читаем весь файл
                    textSplit = str.Split('_');// Расщепляем строку по метке '_'
                    // Элемент textSplit[0] получился пустой
                }
                catch (Exception) { } // Другой синтаксис!!!
                finally
                {
                    // Системные ресурсы надо закрывать
                    myStream.Close();
                    myStreamReader.Close();
                }
        
                // Формируем заголовок программно
                Paragraph head = new Paragraph();
                head.TextAlignment = TextAlignment.Center;
                Run run = new Run("Документ получен расщеплением строки");
                run.FontSize = 21;
                Bold bold = new Bold(run);
                head.Inlines.Add(bold);
                splitDocument.Blocks.Add(head);
        
                // Заполняем FlowDocument
                splitDocument.FontFamily = new FontFamily("Arial");
                for (int i = 1; i < textSplit.Length; i++)
                {
                    Paragraph para = new Paragraph();
                    para.Inlines.Add(textSplit[i]);
                    splitDocument.Blocks.Add(para);
                }
            }
        
            private void listDocument_Initialized(object sender, EventArgs e)
            {
                // Формируем заголовок
                Paragraph head = new Paragraph();
                head.TextAlignment = TextAlignment.Center;
                Run run = new Run("Нумерованный список OrderList");
                run.FontSize = 21;
                Bold bold = new Bold(run);
                head.Inlines.Add(bold);
                listDocument.Blocks.Add(head);
        
                // Создаем и настраиваем список
                List list = new List();
                list.MarkerOffset = 25;// Отступ от маркеров
                list.MarkerStyle = TextMarkerStyle.Decimal;
                list.StartIndex = 3; // Нумерация с 3
        
                // Заполняем список дочерними элементами
                list.ListItems.Add(new ListItem(new Paragraph(new Run("ListItem 1"))));
                list.ListItems.Add(new ListItem(new Paragraph(new Run("ListItem 2"))));
                list.ListItems.Add(new ListItem(new Paragraph(new Run("ListItem 3"))));
                list.ListItems.Add(new ListItem(new Paragraph(new Run("ListItem 4"))));
                list.ListItems.Add(new ListItem(new Paragraph(new Run("ListItem 5"))));
                list.ListItems.Add(new ListItem(new Paragraph(new Run("ListItem 6"))));
                list.ListItems.Add(new ListItem(new Paragraph(new Run("ListItem 7"))));
        
                // Присоединяем список к документу
                listDocument.FontFamily = new FontFamily("Arial");
                listDocument.Blocks.Add(list);
            }
        }
    }
  • Разберитесь с кодом, или выкиньте мой и сочините свой, но чтобы все работало!

Результаты по примерам будут такими:



   


Проповедь

Компьютерные технологии изменяются так стремительно, что некоторым студентам самое время подумать - не пересесть ли с компьютера за штурвал комбайна или не стать ли водителем кобылы. А что, Зелинский, это мысль! Будешь давать стране угля, и дров неналомаешь. Семью обеспечишь, да еще и звезду героя соцтруда могут дать. А у нас, программистов, - одни мозоли в голове, в карманах - вши на арканах, а у преподавателей от таких "студентов" - еще и головная боль впридачу!!! Отпусти нас, Зелинский!

Один из таких комбайнеров написал про меня в Интернете - молодой писака, писательский талант прорезался, на мемуары потянуло, распирать начало. Лучше бы почитывал пока, журналюга... Спасибо, хоть слова не переврал, и то благодаря все тому же Copy-Paste. Почитайте, вам будет поучительно, может станете больше прислушиваться к тому, что я постоянно говорю "Разберитесь с кодом":

http://blogs.mail.ru/mail/vitaliy2525/31E7226B44550EB4.html#

Пописывающий сетует, что что-то делал своими собственными ручками и все работало, но лень было в этом разбираться. А через несколько лет созрел и оказалось, что это красиво - вкусно - полезно. Так причем здесь Снетков?

"Окликнешь, тихо подойдешь, попросишь сторублевку... Причем здесь нож, причем грабеж? - меняй формулировку..." Высоцкий В.С.

Зреть нужно быстрее. Научить ПРОГРАММИРОВАТЬ можно только тех, кто сам этого хочет. Кода я привожу много, на любой вкус и цвет. Разбирайтесь, экспериментируйте, спрашивайте! Но не говорите, что все так плохо и только 'приколы' хороши - это непорядочно.

Высшее профессиональное образование - это не школа благородных девиц. И я не приставленный к ней надзиратель, а свободный преподаватель. Классики, и те уже попритихли. Как научить за мизерное количество часов (и зарплату...)? Заставлять покупать учебники по тысячу рублей штука? Так ведь редко же встречаются целиком стоющие - в одних одно, в других - другое, а большей частью - один хлам.

Взгляните, например, на этот, далеко не полный, ряд 'орудий пристрастья' современного программиста: C#, C++, MFC, VCL, .NET Framework, DirectX, OpenGL, XNA, ADO.NET, SQL, MySQL, SQL Server, Access, Crystal Reports, ASP.NET, HTML, XAML, XML, Windows Forms, WPF, PHP, Ajaxs, сами оболочки C++Builder и MS Visual Studio и т.д. А ведь все это - и есть объектно-ориентированное программирование! И сколько же тысяч нужно заплатить вашим родителям, если все это покупать, чтобы держать себя в форме?

Некоторые из вас и не заметили, что уже пощупали собственными ручками то, о чем ранее даже и не слышали. Все оплачено и налито, только пей. От ' такой методики ' еще никому не поплохело! Знаю, для 'непьющих' хватило бы и Бэйсика, или программирования на листочке, или сразу зачета? Так зачем тогда пришли и на какие средства в дальнейшем собираетесь жить, позвольте спросить, когда ваши родители состарятся и уйдут?

Я не программист, я их уже много лет только готовлю (с перцем, с луком, по собственному рецепту, на приспособах домашнего производства). Есть они не только в Красноярске, можно встретить в Новосибирске, Томске, Железногорске и т.д., и даже... - в Силиконовой долине. Моя ли в том вина, что иногда попадаются подпорченные продукты (я их сам не выбираю), или те, кто сел не в свои сани?

Когда я был маленький, у меня тоже была бабушка. Это было почти вчера, но время летит так быстро: где сейчас маленький, где эта бабушка... Имейте и вы это ввиду - не минет никого чаша сия и нужно все делать вовремя, чтобы успеть состояться в жизни, а не балду гонять! Так что - тужтесь сами, да посильнее, вам 'рожать'. А я на своем месте - стою на вспоможении... (хочешь - напрягайся, буду помогать! не хочешь - дело хозяйское)


Алексей Бабушкин
Алексей Бабушкин

При выполнении в лабораторной работе упражнения №1 , а именно при выполнении нижеследующего кода:

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Text;

using System.Windows.Forms;

using Microsoft.Xna.Framework.Graphics;

   

namespace Application1

{

    public partial class MainForm : Form

    {

        // Объявим поле графического устройства для видимости в методах

        GraphicsDevice device;

   

        public MainForm()

        {

            InitializeComponent();

   

            // Подпишемся на событие Load формы

            this.Load += new EventHandler(MainForm_Load);

   

            // Попишемся на событие FormClosed формы

            this.FormClosed += new FormClosedEventHandler(MainForm_FormClosed);

        }

   

        void MainForm_FormClosed(object sender, FormClosedEventArgs e)

        {

            //  Удаляем (освобождаем) устройство

            device.Dispose();

            // На всякий случай присваиваем ссылке на устройство значение null

            device = null;       

        }

   

        void MainForm_Load(object sender, EventArgs e)

        {

            // Создаем объект представления для настройки графического устройства

            PresentationParameters presentParams = new PresentationParameters();

            // Настраиваем объект представления через его свойства

            presentParams.IsFullScreen = false; // Включаем оконный режим

            presentParams.BackBufferCount = 1;  // Включаем задний буфер

                                                // для двойной буферизации

            // Переключение переднего и заднего буферов

            // должно осуществляться с максимальной эффективностью

            presentParams.SwapEffect = SwapEffect.Discard;

            // Устанавливаем размеры заднего буфера по клиентской области окна формы

            presentParams.BackBufferWidth = this.ClientSize.Width;

            presentParams.BackBufferHeight = this.ClientSize.Height;

   

            // Создадим графическое устройство с заданными настройками

            device = new GraphicsDevice(GraphicsAdapter.DefaultAdapter, DeviceType.Hardware,

                this.Handle, presentParams);

        }

   

        protected override void OnPaint(PaintEventArgs e)

        {

            device.Clear(Microsoft.Xna.Framework.Graphics.Color.CornflowerBlue);

   

            base.OnPaint(e);

        }

    }

}

Выбрасывается исключение:

Невозможно загрузить файл или сборку "Microsoft.Xna.Framework, Version=3.0.0.0, Culture=neutral, PublicKeyToken=6d5c3888ef60e27d" или один из зависимых от них компонентов. Не удается найти указанный файл.

Делаю все пунктуально. В чем может быть проблема?