terminal/src/cascadia/TerminalSettingsEditor/AddProfile.xaml
Mike Griese c18c240627 Manually dismiss popups when the window moves, or the SUI scrolls (#10922)
BODGY!

This solution was suggested in https://github.com/microsoft/microsoft-ui-xaml/issues/4554#issuecomment-887815332.

When the window moves, or when a ScrollViewer scrolls, dismiss any popups that are visible. This happens automagically when an app is a real XAML app, but it doesn't work for XAML Islands.

* upstream at https://github.com/microsoft/microsoft-ui-xaml/issues/4554

* [x] Closes #9320
* [x] I work here
* [ ] Tests added/passed
* [ ] Requires documentation to be updated

Unfortunately, we've got a bunch of scroll viewers in our SUI. So I did something bodgyx2 to make our life a little easier.

`DismissAllPopups` can be used to dismiss all popups for a particular UI element. However, we've got a bunch of pages with scroll viewers that may or may not have popups in them. Rather than define the same exact body for all their `ViewChanging` events, the `HasScrollViewer` struct will just do it for you!

Inside the `HasScrollViewer` stuct, we can't get at the `XamlRoot()` that our subclass implements. I mean, _we_ can, but when XAML does it's codegen, _XAML_ won't be able to figure it out.

Fortunately for us, we don't need to! The sender is a UIElement, so we can just get _their_ `XamlRoot()`.

So, you can fix this for any SUI page with just a simple

```diff
-    <ScrollViewer>
+    <ScrollViewer ViewChanging="ViewChanging">
```

```diff
-    struct AddProfile : AddProfileT<AddProfile>
+    struct AddProfile : public HasScrollViewer<AddProfile>, AddProfileT<AddProfile>
```

* the window doesn't close when you move it
* the popups _do_ close when you move the window
* the popups close when you scroll any SUI page
2021-08-25 17:44:18 -05:00

88 lines
4.6 KiB
XML

<!--
Copyright (c) Microsoft Corporation. All rights reserved. Licensed under
the MIT License. See LICENSE in the project root for license information.
-->
<Page x:Class="Microsoft.Terminal.Settings.Editor.AddProfile"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:Microsoft.Terminal.Settings.Editor"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:model="using:Microsoft.Terminal.Settings.Model"
xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
mc:Ignorable="d">
<Page.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="CommonResources.xaml" />
</ResourceDictionary.MergedDictionaries>
<model:IconPathConverter x:Key="IconSourceConverter" />
</ResourceDictionary>
</Page.Resources>
<ScrollViewer ViewChanging="ViewChanging">
<StackPanel Style="{StaticResource SettingsStackStyle}">
<Button x:Uid="AddProfile_AddNewButton"
AutomationProperties.AutomationId="AddProfile_AddNewButton"
AutomationProperties.Name="{Binding Tag, RelativeSource={RelativeSource Self}}"
Click="AddNewClick"
Style="{StaticResource AccentButtonStyle}">
<Button.Content>
<StackPanel Orientation="Horizontal">
<FontIcon FontSize="{StaticResource StandardIconSize}"
Glyph="&#xE710;" />
<TextBlock x:Uid="AddProfile_AddNewTextBlock"
Style="{StaticResource IconButtonTextBlockStyle}" />
</StackPanel>
</Button.Content>
</Button>
<StackPanel Margin="{StaticResource StandardControlMargin}">
<local:SettingContainer x:Uid="AddProfile_Duplicate">
<muxc:RadioButtons x:Name="Profiles"
ItemsSource="{x:Bind State.Settings.AllProfiles, Mode=OneWay}">
<muxc:RadioButtons.ItemTemplate>
<DataTemplate x:DataType="model:Profile">
<Grid HorizontalAlignment="Stretch"
ColumnSpacing="8">
<Grid.ColumnDefinitions>
<!-- icon -->
<ColumnDefinition Width="16" />
<!-- profile name -->
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<IconSourceElement Grid.Column="0"
Width="16"
Height="16"
IconSource="{x:Bind Icon, Mode=OneWay, Converter={StaticResource IconSourceConverter}}" />
<TextBlock Grid.Column="1"
Text="{x:Bind Name}" />
</Grid>
</DataTemplate>
</muxc:RadioButtons.ItemTemplate>
</muxc:RadioButtons>
</local:SettingContainer>
<Button x:Uid="AddProfile_DuplicateButton"
Margin="{StaticResource StandardControlMargin}"
AutomationProperties.AutomationId="AddProfile_DuplicateButton"
AutomationProperties.Name="{Binding Tag, RelativeSource={RelativeSource Self}}"
Click="DuplicateClick"
Style="{StaticResource AccentButtonStyle}">
<Button.Content>
<StackPanel Orientation="Horizontal">
<FontIcon FontSize="{StaticResource StandardIconSize}"
Glyph="&#xE8C8;" />
<TextBlock x:Uid="AddProfile_DuplicateTextBlock"
Style="{StaticResource IconButtonTextBlockStyle}" />
</StackPanel>
</Button.Content>
</Button>
</StackPanel>
</StackPanel>
</ScrollViewer>
</Page>