Wpf вкладки как в браузере
Добрый день! В Windows Forms я делал класс контрола-наследника вкладки TabPage. Вкладки эти впоследствии динамически создавал и цеплял на TabControl - и работало все замечательно. Подскажите, пожалуйста, как подобное наиболее красиво реализовать в рамках WPF?
Silverlight - не работают собственные классы серверной стороны
Скорее всего, название темы не совсем корректно, т.к. я не знаю как правильно сформулировать его.
Сделать собственные shortcut keys
привет) Скажите, как можно сделать собственный функционал по назначению горячих клавиш и.
Оригинальный интерфейс: создать свои собственные элементы управления: кнопки, бары и т.д.
Задача - требуется создать свои собственные элементы управления: кнопки, бары и т.д. Как я это.
Начать стоит как минимум с того, что представлено в этом примере. Нужно знать также про привязки данных (Binding), шаблоны данных (DataTemplate) и как работать с ItemsControl (TabControl - это ItemsControl)
novikov.ea, потихоньку въезжаю в суть WPF и MVVM. Но постоянно всплывают глупые вопросы - довольно долго до этого писал без использования шаблонов и на WinForms. Например, у меня каждая вкладка динамически отображает периодически обновляемую информацию о некоторых устройствах, подключенных по локальной сети. То есть логика для каждой вкладки реализуется одна и та же, только адрес сети разный используется. Вопрос: где эту самую логику следует реализовать так, чтобы остаться в рамках MVVM и обеспечить одновременную работу нескольких вкладок?
Спасибо.
Решение
То есть логика для каждой вкладки реализуется одна и та же, только адрес сети разный используется. Вопрос: где эту самую логику следует реализовать так, чтобы остаться в рамках MVVM и обеспечить одновременную работу нескольких вкладок?
Я бы сделал так:
Написал бы логику, которая работает с устройствами, то есть какой-то класс. У класса бы сделал события, которые бы оповещали о чём-то, например, о подключении устройства, об отключении, о обновлении данных. Это Model. Далее я бы во ViewModel создал экземпляр этого класса, подписался бы на события и обновлял бы свойства ViewModel, значения которых бы автоматом ототбражались во View посредством биндингов.
В примере используется библиотека GalaSoft.MvvmLight, чтобы проект собрался, нужно восстановить NuGet пакеты. Если автоматом не восстановятся при сборке, то читай: Восстановление пакетов. В общем, я не думаю, что тут возникнут проблемы, гуглится в 3 секунды, что и как.
Ещё момент, который хотел бы упомянуть. Это просто пример, в каждом конкретном случае могут быть свои нюансы и реализация может отличаться. Я что придумал, то и набросал по быстрому.
Остальной код во вложении. Там создаются 3 вкладки, как бы 3 устройства. И с определённой периодичностью обновляются данные.
Я бы сделал так:
Написал бы логику, которая работает с устройствами, то есть какой-то класс. У класса бы сделал события, которые бы оповещали о чём-то, например, о подключении устройства, об отключении, о обновлении данных. Это Model. Далее я бы во ViewModel создал экземпляр этого класса, подписался бы на события и обновлял бы свойства ViewModel, значения которых бы автоматом ототбражались во View посредством биндингов.
Воспользовался Вашим советом. Вышло следующее:
Есть одна View (MainWindowViewModel), на которой в процессе поиска устройств (DeviceSearcher) добавляются вкладки. После добавления последних запускается логика, имплементированная в DeviceMan. Моделями представления выступают MainWindowViewModel и TabItemViewModel, соответственно, выступающих в качестве контекста данных главного окна и ObservableCollection для ItemsSource'a TabControl'a (в). ViewModel'ы взаимодействуют с методами классов Model с помощью событий, например, так:
Ну а View взаимодействует с ViewModel посредством команд.
Правильно ли я двигаюсь? На данном этапе непонятен вопрос, как обеспечить взаимодействие двух ViewModel - это мне нужно для того, чтобы как-то обновлять StatusBar не только из главной модели представления, а, например, в процессе работы методов класса DeviceMan, используемого в TabItemViewModel.
P.S. Использовать какие-либо Mvvm Toolkit'ы и Prism'ы пока не планирую - хочу для начала научиться делать все сам.
Пока со StatusBar'ом решил так: создал ViewModelBase, от которой унаследовал все модели представления, запихнул туда реализацию INPC и свойство-строку, к которой биндится StatusBar; здесь же завел команду со ссылкой на метод, где это свойство принимает значение передаваемого в параметре.
Добавлено через 1 час 46 минут
Буду здесь же, если никто не против, задавать несколько иные вопросы в рамках моих задач, дабы не городить темы. Вот, например, еще задачка:
Вот есть у меня главное окно программы, в нем TabControl. tabControl содержит Grid с двумя столбцами. Нужно по нажатию кнопки выносить содержимое правого столбца в отдельное окно. Дескать, смена режима вида. Как бы такое реализовать?
Нужно по нажатию кнопки выносить содержимое правого столбца в отдельное окно. Дескать, смена режима вида. Как бы такое реализовать?
Элемент TabControl позволяет создать элемент управления с несколькими вкладками. И каждая вкладка будет хранить некоторый набор других элементов управления, как кнопки, текстовые поля и др. Каждая вкладка представлена классом TabPage.
Чтобы настроить вкладки элемента TabControl используем свойство TabPages. При переносе элемента TabControl с панели инструментов на форму по умолчанию создаются две вкладки - tabPage1 и tabPage2. Изменим их отображение с помощью свойства TabPages:
Нам откроется окно редактирования/добавления и удаления вкладок:
Каждая вкладка представляет своего рода панель, на которую мы можем добавить другие элементы управления, а также заголовок, с помощью которого мы можем переключаться по вкладкам. Текст заголовка задается с помощью свойства Text.
Управление вкладками в коде
Для добавления новой вкладки нам надо ее создать и добавить в коллекцию tabControl1.TabPages с помощью метода Add:
Удаление так же просто:
Получая в коллекции tabControl1.TabPages нужную вкладку по индексу, мы можем ей легко манипулировать:
SplitContainer
Элемент SplitContainer позволяет создавать две разделенные сплитером панели. Изменяя положение сплитера, можно изменить размеры этих панелей.
Используя свойство Orientation , можно задать горизонтальное или вертикальное отображение сплитера на форму. В данном случае это свойство принимает значения Horisontal и Vertical соответственно.
В случае, когда надо запретить изменение положения сплиттера, то можно присвоить свойству IsSplitterFixed значение true . Таким образом, сплитер окажется фиксированным, и мы не сможем поменять его положение.
По умолчанию при растяжении формы или ее сужении также будет меняться размер обеих панелей сплитконтейнера. Однако мы можем закрепить за одной панелью фиксированную ширину (при вертикальной ориентации сплиттера) или высоту (при горизонтальной ориентации сплиттера). Для этого нам надо установить у элемента SplitContainer свойство FixedPanel . В качестве значения оно принимает панель, которую надо зафиксировать:
Чтобы изменить положение сплитера в коде, мы можем управлять свойством SplitterDistance , которое задает положение сплиттера в пикселях от левого или верхнего края элемента SplitContainer. А с помощью свойства SplitterIncrement можно задать шаг, на который будет перемещаться сплиттер при движении его с помощью клавиш-стрелок.
Чтобы скрыть одну из двух панелей, мы можем установить свойство Panel1Collapsed или Panel2Collapsed в true
The WPF TabControl allows you to split your interface up into different areas, each accessible by clicking on the tab header, usually positioned at the top of the control. Tab controls are commonly used in Windows applications and even within Windows' own interfaces, like the properties dialog for files/folders etc.
Just like with most other WPF controls, the TabControl is very easy to get started with. Here's a very basic example:
As you can see, each tab is represented with a TabItem element, where the text shown on it is controlled by the Header property. The TabItem element comes from the ContentControl class, which means that you may define a single element inside of it that will be shown if the tab is active (like on the screenshot). I used a Label in this example, but if you want to place more than one control inside of the tab, just use one of the panels with child controls inside of it.
Customized headers
Once again, WPF proves to be extremely flexible when you want to customize the look of your tabs. Obviously the content can be rendered any way you like it, but so can the tab headers! The Header property can be filled with anything you like, which we'll take advantage of in the next example:
The amount of markup might be a bit overwhelming, but as you can probably see once you dig into it, it's all very simple. Each of the tabs now has a TabControl.Header element, which contains a StackPanel, which in turn contains an Image and a TextBlock control. This allows us to have an image on each of the tabs as well as customize the color of the text (we could have made it bold, italic or another size as well).
Controlling the TabControl
Sometimes you may wish to control which tab is selected programmatically or perhaps get some information about the selected tab. The WPF TabControl has several properties which makes this possible, including SelectedIndex and SelectedItem. In the next example, I've added a couple of buttons to the first example which allows us to control the TabControl:
As you can see, I've simply added a set of buttons in the lower part of the interface. The first two allows will select the previous or next tab on the control, while the last one will display information about the currently selected tab, as demonstrated on the screenshot.
The first two buttons uses the SelectedIndex property to determine where we are and then either subtracts or adds one to that value, making sure that the new index doesn't fall below or above the amount of available items. The third button uses the SelectedItem property to get a reference to the selected tab. As you can see, I have to typecast it into the TabItem class to get a hold of the header property, since the SelectedProperty is of the object type by default.
Summary
The TabControl is great when you need a clear separation in a dialog or when there's simply not enough space for all the controls you want in it. In the next couple of chapters, we'll look into some of the possibilites there are when using the TabControl for various purposes.
Is your preferred language not on the list? Click here to help us translate this article into your language!
Элемент управления WPF TabControl позволяет разбить ваш интерфейс на несколько разных зон, которые можно выбрать нажав на заголовок, который обычно находится сверху элемента управления. Вкладки широко используются в приложениях для Windows, и даже в интерфейсах самой Windows, таких как диалоговые окна для выбора файлов, папок и так далее.
Как и в случае с другими элементами управления WPF, начать работу с вкладками при помощи TabControl несложно. Вот несколько простых примеров:
Как видите, каждой вкладке соответствует элемент TabItem, текст которой задается свойством Header. Элемент TabItem наследует класс ContentControl, и это значит, что вы можете определить в качестве содержания одиночный элемент, который отображается, когда вкладка активна (как на снимке экрана). Я использую в этом примере элемент управления Label, но при желании вы можете разместить внутри вкладки несколько элементов, просто используя для этого панели с дочерними элементами внутри.
Customized headers
Повторюсь, WPF обеспечивает чрезвычайную гибкость, когда вы хотите настроить внешний вид ваших вкладок. Само собой, содержание вкладок можно отобразить совершенно разными способами, но это же касается и заголовков! Свойство Header также можно наполнить различными элементами управления и мы воспользуемся этим в следующем примере:
Вариантов разметки так много, что это может показаться слишком сложным, но, стоит только начать и все окажется очень просто. Теперь в каждой вкладке есть элемент TabControl.Header содержащий StackPanel, в котором в свою очередь находятся элементы управления Image и TextBlock. Это позволяет прикрепить к каждой вкладке свою картинку, выбрать цвет текста (еще можно выбрать полужирное, курсивное начертание или другой размер).
Способы управления TabControl
Иногда может возникнуть необходимость программно управлять выбором вкладок или, может быть, узнать какая из них активна. В WPF TabControl для этого есть несколько способов, включая SelectedIndex и SelectedItem. В следующем примере я добавил несколько кнопок в первый из них, что позволяет управлять поведением TabControl:
Как видите, я просто добавил набор кнопок в нижнюю часть окна. Первые две дают возможность выбрать предыдущую или следующую вкладку, тогда как последняя показывает информацию об активной вкладке, как показано на снимке экрана.
Первые две кнопки, чтобы определить, где мы находимся используют свойство SelectedIndex, а затем мы увеличиваем или уменьшаем это значение, проверяя, не выходит ли индекс за пределы. Третья кнопка получает ссылку на активную вкладку с помощью свойства SelectedItem. Как можно заметить, ее необходимо привести к типу TabItem, чтобы получить доступ к свойству Header, так как SelectedProperty по умолчанию имеет тип object.
Резюме
TabControl замечательно подходит, когда необходимо четкое разделение в диалоговом окне или когда просто не хватает места. В следующих главах мы рассмотрим некоторые возможности использования элемента управления Tab для различных целей.
Is your preferred language not on the list? Click here to help us translate this article into your language!
WPF поставляется с готовым к использованию элементом управления WebBrowser, который позволяет разместить готовый веб-браузер в вашем приложении. Элемент управления WebBrowser в действительности просто оболочка вокруг версии ActiveX для Internet Explorer, но с тех пор как ActiveX стал интегрированной частью Windows, ваше приложение должно работать на всех машинах с установленной Windows, без требования к установке дополнительных компонентов.
В этой статье я сделал немного по-другому: вместо того, чтобы начинать с простого примера, а затем по немногу его усложнять, я создал один, но более сложный пример. Он показывает, как легко вы можете получить маленький веб-браузер и запустить его. Он будет очень простым по своей функциональности, но вы можете легко расширьте его возможности, если захотите. Вот как это выглядит:
Итак, давайте взглянем на код:
Сначала код может показаться немного пугающим, но если вы взгляните на него еще раз, то увидите, что в нем много повторений.
Давайте начнем с обсуждения XAML части. Обратите внимание, я использую несколько понятий, рассмотренных в этом руководстве, включая ToolBar(Панель управления) и команды WPF. ToolBar используется для размещения нескольких кнопок, используемых для перемещения вперед и назад. Далее у нас есть адресная строка для ввода и отображение текущего URL-адреса, вместе с кнопкой для перехода к введенному URL.
Под Toolbar у нас расположен компонент WebBrowser. Как вы можете заметить, для его использования требуется только одна строка XAML - в данном случае мы подписываемся на событие Navigating, которое происходит, как только WebBrowser начинает переход по URL-адресу.
В фоновом коде, мы начинаем с перехода по URL-Адресу, расположенного в конструкторе окна, чтобы было что показать, вместо пустого элемента управления. Затем у нас есть событие txtUrl_KeyUp , в котором мы проверяем, нажал ли пользователь Enter внутри адресной строки - если это так, то мы начнем переход к введенному URL.
Событие wbSample_Navigating гарантирует, что адресная строка будет обновляться каждый раз при переходе на новую страницу. Это важно, потому что мы хотим, чтобы адресная строка отображала текущий URL-адрес в независимости от того, начал ли пользователь переход на новую страницу, введя новый URL-адрес или щелкнув на ссылку веб-страницы.
Последняя часть фонового кода - это простая обработка наших команд: Две для кнопок назад и вперед, в которых мы используем CanGoBack и CanGoForward для определения, могут ли они выполняться, и методы GoBack и GoForward для того чтобы выполнить фактическую работу. Это обычное дело при работе с командами в WPF, как и описано в разделе команды, данного руководства.
К последней команде, мы позволяем ей постоянно выполняться, и когда она завершиться, мы снова используем метод Navigate ().
Коротко о вышесказанном
Как вы можете заметить, запустить и использовать веб браузер внутри вашего приложения стало очень легко с использованием компонента WebBrowser. Однако, нужно учитывать, что версия WPF WebBrowser немного ограничена по сравнению с версией WinForms, но для базового использования и навигации она работает отлично.
Если вы хотите использовать версию WinForms, вы можете сделать это с помощью WindowsFormsHost, о котором идет речь в другом месте этого руководства.
Is your preferred language not on the list? Click here to help us translate this article into your language!
Читайте также: