Skip to content
This repository was archived by the owner on Nov 29, 2022. It is now read-only.

Commit 7fe8c31

Browse files
Add Tab Tear-off creating new window.
1 parent 05ad628 commit 7fe8c31

File tree

4 files changed

+101
-16
lines changed

4 files changed

+101
-16
lines changed

TabViewTear/Services/ViewLifetimeControl.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,12 @@ public sealed class ViewLifetimeControl
2828
// This id is used in all of the ApplicationViewSwitcher and ProjectionManager APIs
2929
public int Id { get; private set; }
3030

31+
// Initial title for the window
3132
public string Title { get; set; }
3233

34+
// Optional context to provide from window opener
35+
public string Context { get; set; }
36+
3337
public event ViewReleasedHandler Released
3438
{
3539
add

TabViewTear/Services/WindowManagerService.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,9 @@ public void Initialize()
3636

3737
// Displays a view as a standalone
3838
// You can use the resulting ViewLifeTileControl to interact with the new window.
39-
public async Task<ViewLifetimeControl> TryShowAsStandaloneAsync(string windowTitle, Type pageType)
39+
public async Task<ViewLifetimeControl> TryShowAsStandaloneAsync(string windowTitle, Type pageType, string dataContext = null)
4040
{
41-
ViewLifetimeControl viewControl = await CreateViewLifetimeControlAsync(windowTitle, pageType);
41+
ViewLifetimeControl viewControl = await CreateViewLifetimeControlAsync(windowTitle, pageType, dataContext);
4242
SecondaryViews.Add(viewControl);
4343
viewControl.StartViewInUse();
4444
var viewShown = await ApplicationViewSwitcher.TryShowAsStandaloneAsync(viewControl.Id, ViewSizePreference.Default, ApplicationView.GetForCurrentView().Id, ViewSizePreference.Default);
@@ -57,14 +57,15 @@ public async Task<ViewLifetimeControl> TryShowAsViewModeAsync(string windowTitle
5757
return viewControl;
5858
}
5959

60-
private async Task<ViewLifetimeControl> CreateViewLifetimeControlAsync(string windowTitle, Type pageType)
60+
private async Task<ViewLifetimeControl> CreateViewLifetimeControlAsync(string windowTitle, Type pageType, string dataContext = null)
6161
{
6262
ViewLifetimeControl viewControl = null;
6363

6464
await CoreApplication.CreateNewView().Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
6565
{
6666
viewControl = ViewLifetimeControl.CreateForCurrentView();
6767
viewControl.Title = windowTitle;
68+
viewControl.Context = dataContext;
6869
viewControl.StartViewInUse();
6970
var frame = new Frame();
7071
frame.RequestedTheme = ThemeSelectorService.Theme;

TabViewTear/Views/MainPage.xaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@
1212
TabWidthBehavior="Equal"
1313
SelectedTabWidth="200"
1414
x:Name="Items"
15+
CanDragItems="True"
16+
CanReorderItems="True"
17+
AllowDrop="True"
18+
TabDraggedOutside="Items_TabDraggedOutside"
19+
SelectionChanged="Items_SelectionChanged"
1520
ItemsSource="{x:Bind TabItems}">
1621
<controls:TabView.Resources>
1722
<x:Double x:Key="TabViewItemHeaderMinWidth">90</x:Double>

TabViewTear/Views/MainPage.xaml.cs

Lines changed: 88 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,16 @@
1-
using System;
1+
using Newtonsoft.Json;
2+
using System;
23
using System.Collections.ObjectModel;
34
using System.ComponentModel;
5+
using System.Linq;
46
using System.Runtime.CompilerServices;
57
using TabViewTear.Models;
8+
using TabViewTear.Services;
9+
using Windows.UI.Core;
10+
using Windows.UI.ViewManagement;
11+
using Windows.UI.Xaml;
612
using Windows.UI.Xaml.Controls;
13+
using Windows.UI.Xaml.Navigation;
714

815
namespace TabViewTear.Views
916
{
@@ -14,25 +21,69 @@ public sealed partial class MainPage : Page, INotifyPropertyChanged
1421
public MainPage()
1522
{
1623
InitializeComponent();
24+
}
1725

18-
TabItems.Add(new DataItem()
26+
public event PropertyChangedEventHandler PropertyChanged;
27+
28+
private ViewLifetimeControl _viewLifetimeControl;
29+
protected override void OnNavigatedTo(NavigationEventArgs e)
30+
{
31+
base.OnNavigatedTo(e);
32+
33+
_viewLifetimeControl = e.Parameter as ViewLifetimeControl;
34+
if (_viewLifetimeControl != null)
1935
{
20-
Title = "Item 1",
21-
Content = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur a consectetur arcu, eu imperdiet nisl. Nunc id interdum odio. Aliquam non vulputate sem. Proin lacinia, lacus vitae finibus malesuada, leo libero interdum nisl, et dictum justo tortor semper tortor. Phasellus suscipit malesuada ultrices. Cras sodales vel lectus quis mattis. Sed consequat mollis ultrices. Nam eleifend purus sit amet massa mattis facilisis. Donec fringilla convallis nibh eget venenatis. Morbi ac venenatis ex. Integer ultrices velit eget dictum ultrices. Nunc aliquet lectus vitae feugiat varius. Nulla erat nisi, scelerisque ut sollicitudin id, vestibulum at mi. Donec neque velit, ornare consectetur aliquet id, egestas nec sapien. Nulla nec magna sed nunc varius bibendum."
22-
});
23-
TabItems.Add(new DataItem()
36+
_viewLifetimeControl.StartViewInUse();
37+
// Register for window close
38+
_viewLifetimeControl.Released += OnViewLifetimeControlReleased;
39+
// Deserialize passed in item to display in this window
40+
TabItems.Add(JsonConvert.DeserializeObject<DataItem>(_viewLifetimeControl.Context.ToString()));
41+
_viewLifetimeControl.Context = null;
42+
_viewLifetimeControl.StopViewInUse();
43+
}
44+
else
2445
{
25-
Title = "Item 2",
26-
Content = "Aliquam fringilla euismod neque sit amet porta. Aliquam et ligula in neque ullamcorper interdum sit amet et magna. Quisque maximus accumsan lorem at rhoncus. Pellentesque mattis, eros non accumsan auctor, libero turpis sodales urna, id porta mi dolor at elit. Interdum et malesuada fames ac ante ipsum primis in faucibus. Donec lacinia leo arcu, vitae malesuada sapien consequat eget. Pellentesque vestibulum interdum convallis. Mauris nulla elit, tempus sit amet enim finibus, suscipit tempor ante. Nullam pulvinar libero sed tincidunt sagittis. Suspendisse potenti. Nulla porta lacinia lacus vel bibendum. Sed sagittis dignissim leo, ac gravida sem mattis pellentesque."
27-
});
28-
TabItems.Add(new DataItem()
46+
// Main Window Start
47+
InitializeTestData();
48+
}
49+
}
50+
51+
private async void OnViewLifetimeControlReleased(object sender, EventArgs e)
52+
{
53+
_viewLifetimeControl.Released -= OnViewLifetimeControlReleased;
54+
await WindowManagerService.Current.MainDispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
2955
{
30-
Title = "Item 3",
31-
Content = "Donec tellus nisl, volutpat vel urna eu, vestibulum sollicitudin sapien. Aliquam libero ex, egestas ut dapibus ullamcorper, mattis non nisl. Pellentesque quis hendrerit nibh. In lobortis placerat interdum. Aliquam et eleifend velit. Nunc ipsum orci, auctor eget eros non, euismod accumsan quam. Nam sit amet convallis est. Integer eget mauris pharetra, fringilla elit a, eleifend felis. Nullam vel ex posuere, blandit tellus nec, lobortis mauris. Nulla rhoncus nisi vel leo condimentum, non cursus lacus tempus. "
56+
WindowManagerService.Current.SecondaryViews.Remove(_viewLifetimeControl);
3257
});
3358
}
3459

35-
public event PropertyChangedEventHandler PropertyChanged;
60+
private async void Items_TabDraggedOutside(object sender, Microsoft.Toolkit.Uwp.UI.Controls.TabDraggedOutsideEventArgs e)
61+
{
62+
if (e.Item is DataItem data)
63+
{
64+
// Need to serialize item to better provide transfer across window threads.
65+
var lifetimecontrol = await WindowManagerService.Current.TryShowAsStandaloneAsync(data.Title, typeof(MainPage), JsonConvert.SerializeObject(data));
66+
67+
// Remove Dragged Tab from this window
68+
TabItems.Remove(data);
69+
70+
if (TabItems.Count == 0)
71+
{
72+
// No tabs left on main window, 'switch' to window just created to hide the main view
73+
await ApplicationViewSwitcher.SwitchAsync(lifetimecontrol.Id, ApplicationView.GetForCurrentView().Id, ApplicationViewSwitchingOptions.ConsolidateViews);
74+
}
75+
}
76+
}
77+
78+
private void Items_SelectionChanged(object sender, SelectionChangedEventArgs e)
79+
{
80+
// Update window title with current item
81+
var first = e.AddedItems.FirstOrDefault();
82+
if (first is DataItem data)
83+
{
84+
ApplicationView.GetForCurrentView().Title = data.Title;
85+
}
86+
}
3687

3788
private void Set<T>(ref T storage, T value, [CallerMemberName]string propertyName = null)
3889
{
@@ -46,5 +97,29 @@ private void Set<T>(ref T storage, T value, [CallerMemberName]string propertyNam
4697
}
4798

4899
private void OnPropertyChanged(string propertyName) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
100+
101+
private void InitializeTestData()
102+
{
103+
TabItems.Add(new DataItem()
104+
{
105+
Title = "Item 1",
106+
Content = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur a consectetur arcu, eu imperdiet nisl. Nunc id interdum odio. Aliquam non vulputate sem. Proin lacinia, lacus vitae finibus malesuada, leo libero interdum nisl, et dictum justo tortor semper tortor. Phasellus suscipit malesuada ultrices. Cras sodales vel lectus quis mattis. Sed consequat mollis ultrices. Nam eleifend purus sit amet massa mattis facilisis. Donec fringilla convallis nibh eget venenatis. Morbi ac venenatis ex. Integer ultrices velit eget dictum ultrices. Nunc aliquet lectus vitae feugiat varius. Nulla erat nisi, scelerisque ut sollicitudin id, vestibulum at mi. Donec neque velit, ornare consectetur aliquet id, egestas nec sapien. Nulla nec magna sed nunc varius bibendum."
107+
});
108+
TabItems.Add(new DataItem()
109+
{
110+
Title = "Item 2",
111+
Content = "Aliquam fringilla euismod neque sit amet porta. Aliquam et ligula in neque ullamcorper interdum sit amet et magna. Quisque maximus accumsan lorem at rhoncus. Pellentesque mattis, eros non accumsan auctor, libero turpis sodales urna, id porta mi dolor at elit. Interdum et malesuada fames ac ante ipsum primis in faucibus. Donec lacinia leo arcu, vitae malesuada sapien consequat eget. Pellentesque vestibulum interdum convallis. Mauris nulla elit, tempus sit amet enim finibus, suscipit tempor ante. Nullam pulvinar libero sed tincidunt sagittis. Suspendisse potenti. Nulla porta lacinia lacus vel bibendum. Sed sagittis dignissim leo, ac gravida sem mattis pellentesque."
112+
});
113+
TabItems.Add(new DataItem()
114+
{
115+
Title = "Item 3",
116+
Content = "Donec tellus nisl, volutpat vel urna eu, vestibulum sollicitudin sapien. Aliquam libero ex, egestas ut dapibus ullamcorper, mattis non nisl. Pellentesque quis hendrerit nibh. In lobortis placerat interdum. Aliquam et eleifend velit. Nunc ipsum orci, auctor eget eros non, euismod accumsan quam. Nam sit amet convallis est. Integer eget mauris pharetra, fringilla elit a, eleifend felis. Nullam vel ex posuere, blandit tellus nec, lobortis mauris. Nulla rhoncus nisi vel leo condimentum, non cursus lacus tempus."
117+
});
118+
TabItems.Add(new DataItem()
119+
{
120+
Title = "Item 4",
121+
Content = "Nullam sollicitudin magna dui, imperdiet vulputate arcu pharetra eu. Vivamus lobortis lectus ut diam pretium, ut fermentum est malesuada. Sed eget pretium nisi. Cras eget vestibulum purus. Vivamus tincidunt luctus maximus. Cras erat enim, molestie sit amet tortor sit amet, porttitor tincidunt neque. Nam malesuada odio justo, sed sagittis tellus mollis in. Proin congue enim quis libero faucibus, eu condimentum dolor convallis. Mauris blandit ipsum sit amet maximus convallis. Integer porta dolor id purus hendrerit, a semper mi blandit. In malesuada lacus a tellus interdum, vel consequat turpis molestie. Curabitur eget venenatis massa."
122+
});
123+
}
49124
}
50125
}

0 commit comments

Comments
 (0)