Reputation: 15
I am writing a terminal in WPF, which communicates the host with an embedded device through RS232. I want to be able to open multiple connections that will reside on different tabs, I believe that for that purpose WPF's tabContorl is sufficient, However the customer wants to be able to tile the different tabs on the screen, and as I understand the basic tabControl doesn't allow you to do that.
Any ideas how can this be done?
any help will be appreciated, Thanks in advance.
Upvotes: 1
Views: 737
Reputation: 13177
I have made a custom WPF control called ModalContentPresenter
that allows you to display modal content which I think will be suitable. The control allows you to conditionally display additional content on top of your primary content.
Your application window will comprise a single ModalContentPresenter
which will contain your TabControl
in it's primary content and an ItemsControl
in it's modal content.
<c:ModalContentPresenter IsModal="{Binding IsTiling}">
<DockPanel>
<Button Content="Show tiled view"
Command={Binding ShowTiledViewCommand}
DockPanel.Dock="Top"/>
<TabControl ItemsSource="{Binding Connections}"> />
</DockPanel>
<c:ModalContentPresenter.ModalContent>
<DockPanel>
<Button Content="Hide tiled view"
Command={Binding HideTiledViewCommand}
DockPanel.Dock="Top"/>
<Itemscontrol ItemsSource="{Binding Connections}" />
</DockPanel>
</c:ModalContentPresenter.ModalContent>
</c:ModalContentPresenter>
TabControl
.TabControl
and ItemsControl
are bound to the same collection of data in your viewModel ensuring that the tiled view is in sync with the items in the tab control.Boolean
property called IsTiling
which should return true
when you want the 'tiled' view to be shown and false
when it is hidden.ItemsControl
to change how the collection of data is 'tiled'.See this answer for an additional example of how to use the control.
The interface of your viewModel will look something like this:
public interface ViewModel {
public ObservableCollection<Connection> Connections { get; }
public boolean IsTiling { get; }
public ICommand ShowTiledViewCommand { get; }
public ICommand HideTiledViewCommand { get; }
}
Once you have this working you can add some additional enhancements to improve the look and feel of the user interface.
I would start by assigning a custom control template to the TabControl
so that a Button
is displayed in the 'header' area. This Button
is bound to a command in your viewModel which is responsible for changing the IsTiling
property to true
.
This question provides a link to an answer which explores ways of achieving this.
A second enhancement is to remove the button from the modal content and call the HideTiledViewCommand
command when the user selects an item in the items control. You can then add some additional logic which selects the correct tab when the tiled view is closed. I think this can be achieved by having an additional property in your viewModel representing the selected connection.
Upvotes: 1
Reputation: 12616
Maybe it's overkill, but I would give a try to Avalon Dock from the WPF Toolkit, it's free. With that, you will be able to move terminals around, dock them wherever you wish and even have only opened at a time if you unpin others.
Upvotes: 2