add: views/unitconverter.xaml (#11)

* add: views/unitconverter.xaml

* format the code

* remove the extra empty line

* add an empty line
This commit is contained in:
Tian L 2021-04-12 17:00:40 +08:00 committed by GitHub
commit e2b384198a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 1415 additions and 40 deletions

View file

@ -35,6 +35,11 @@ namespace CalculatorApp
}
}
int GetModelCategoryId()
{
return GetModelCategory().id;
}
internal : const UnitConversionManager::Category& GetModelCategory() const
{
return m_original;
@ -116,7 +121,7 @@ namespace CalculatorApp
OBSERVABLE_PROPERTY_R(CalculatorApp::ViewModel::Unit ^, Unit);
};
interface class IActivatable
public interface class IActivatable
{
virtual property bool IsActive;
};
@ -232,12 +237,14 @@ namespace CalculatorApp
void AnnounceConversionResult();
void OnPaste(Platform::String ^ stringToPaste);
void RefreshCurrencyRatios();
void OnValueActivated(IActivatable ^ control);
internal : void ResetView();
void PopulateData();
NumbersAndOperatorsEnum MapCharacterToButtonId(const wchar_t ch, bool& canSendNegate);
void DisplayPasteError();
void OnValueActivated(IActivatable ^ control);
void OnPaste(Platform::String ^ stringToPaste);
void OnCopyCommand(Platform::Object ^ parameter);
void OnPasteCommand(Platform::Object ^ parameter);
@ -270,7 +277,6 @@ namespace CalculatorApp
void OnCurrencyDataLoadFinished(bool didLoad);
void OnCurrencyTimestampUpdated(_In_ const std::wstring& timestamp, bool isWeekOld);
void RefreshCurrencyRatios();
void OnNetworkBehaviorChanged(_In_ CalculatorApp::NetworkAccessBehavior newBehavior);
const std::wstring& GetValueFromUnlocalized() const

View file

@ -227,6 +227,9 @@
<Compile Include="Views\TitleBar.xaml.cs">
<DependentUpon>TitleBar.xaml</DependentUpon>
</Compile>
<Compile Include="Views\UnitConverter.xaml.cs">
<DependentUpon>UnitConverter.xaml</DependentUpon>
</Compile>
<Compile Include="WindowFrameService.cs" />
<Compile Include="WinMeta.cs" />
</ItemGroup>
@ -631,6 +634,10 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Views\DelighterUnitStyles.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Views\GraphingCalculator\EquationInputArea.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
@ -687,6 +694,10 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Views\UnitConverter.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NETCore.UniversalWindowsPlatform">

View file

@ -0,0 +1,216 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:CalculatorApp">
<Style x:Key="DelighterBaseStyle" TargetType="TextBlock">
<Setter Property="FontFamily" Value="Segoe UI Symbol"/>
<Setter Property="FontSize" Value="20"/>
<Setter Property="IsTextScaleFactorEnabled" Value="False"/>
<Setter Property="Foreground" Value="{ThemeResource SystemControlPageTextBaseHighBrush}"/>
<Setter Property="Padding" Value="0"/>
<Setter Property="Margin" Value="0,3,8,-3"/>
</Style>
<Style x:Key="Unit_118"
BasedOn="{StaticResource DelighterBaseStyle}"
TargetType="TextBlock">
<!-- Hand #1 (Area) -->
<Setter Property="Text" Value="👋"/>
<Setter Property="Margin" Value="0,3,8,-3"/>
</Style>
<Style x:Key="Unit_127"
BasedOn="{StaticResource DelighterBaseStyle}"
TargetType="TextBlock">
<!-- Paper -->
<Setter Property="Text" Value="📄"/>
<Setter Property="Margin" Value="0,3,8,-3"/>
</Style>
<Style x:Key="Unit_99"
BasedOn="{StaticResource DelighterBaseStyle}"
TargetType="TextBlock">
<!-- Soccer field -->
<Setter Property="Text" Value="⚽"/>
<Setter Property="Margin" Value="0,3,10,-3"/>
</Style>
<Style x:Key="Unit_128"
BasedOn="{StaticResource DelighterBaseStyle}"
TargetType="TextBlock">
<!-- Castle -->
<Setter Property="Text" Value="🏰"/>
<Setter Property="Margin" Value="0,2,10,-2"/>
</Style>
<Style x:Key="Unit_100"
BasedOn="{StaticResource DelighterBaseStyle}"
TargetType="TextBlock">
<!-- Floppy disk -->
<Setter Property="Text" Value="💾"/>
<Setter Property="Margin" Value="0,3,9,-3"/>
</Style>
<!-- Duplicate of Unit_97 as CD appears twice in config -->
<Style x:Key="Unit_101"
BasedOn="{StaticResource DelighterBaseStyle}"
TargetType="TextBlock">
<!-- CD -->
<Setter Property="Text" Value="💿"/>
<Setter Property="Margin" Value="0,3,9,-3"/>
</Style>
<Style x:Key="Unit_102"
BasedOn="{StaticResource DelighterBaseStyle}"
TargetType="TextBlock">
<!-- DVD -->
<Setter Property="Text" Value="📀"/>
<Setter Property="Margin" Value="0,3,10,-3"/>
</Style>
<Style x:Key="Unit_103"
BasedOn="{StaticResource DelighterBaseStyle}"
TargetType="TextBlock">
<!-- Battery -->
<Setter Property="Text" Value="🔋"/>
<Setter Property="Margin" Value="0,3,10,-3"/>
</Style>
<Style x:Key="Unit_129"
BasedOn="{StaticResource DelighterBaseStyle}"
TargetType="TextBlock">
<!-- Banana -->
<Setter Property="Text" Value="🍌"/>
</Style>
<Style x:Key="Unit_130"
BasedOn="{StaticResource DelighterBaseStyle}"
TargetType="TextBlock">
<!-- Slice of cake -->
<Setter Property="Text" Value="🍰"/>
</Style>
<Style x:Key="Unit_105"
BasedOn="{StaticResource DelighterBaseStyle}"
TargetType="TextBlock">
<!-- Paperclip -->
<Setter Property="Text" Value="📎"/>
<Setter Property="Margin" Value="0,3,6,-3"/>
</Style>
<Style x:Key="Unit_131"
BasedOn="{StaticResource Unit_118}"
TargetType="TextBlock">
<!-- Hand #2 (Length) -->
</Style>
<Style x:Key="Unit_107"
BasedOn="{StaticResource DelighterBaseStyle}"
TargetType="TextBlock">
<!-- Jumbojet -->
<Setter Property="Text" Value="✈"/>
<Setter Property="Margin" Value="0,2,8,-2"/>
</Style>
<Style x:Key="Unit_108"
BasedOn="{StaticResource DelighterBaseStyle}"
TargetType="TextBlock">
<!-- Lightbulb -->
<Setter Property="Text" Value="💡"/>
<Setter Property="Margin" Value="0,3,10,-3"/>
</Style>
<Style x:Key="Unit_109"
BasedOn="{StaticResource DelighterBaseStyle}"
TargetType="TextBlock">
<!-- Horse -->
<Setter Property="Text" Value="🐎"/>
<Setter Property="Margin" Value="0,3,8,-2"/>
</Style>
<Style x:Key="Unit_132"
BasedOn="{StaticResource DelighterBaseStyle}"
TargetType="TextBlock">
<!-- Train Engine -->
<Setter Property="Text" Value="🚂"/>
<Setter Property="Margin" Value="0,2,9,-2"/>
</Style>
<Style x:Key="Unit_121"
BasedOn="{StaticResource DelighterBaseStyle}"
TargetType="TextBlock">
<!-- Turtle -->
<Setter Property="Text" Value="🐢"/>
<Setter Property="Margin" Value="0,2,9,-2"/>
</Style>
<Style x:Key="Unit_126"
BasedOn="{StaticResource Unit_109}"
TargetType="TextBlock">
<!-- Horse -->
</Style>
<Style x:Key="Unit_122"
BasedOn="{StaticResource DelighterBaseStyle}"
TargetType="TextBlock">
<!-- Jet -->
<Setter Property="Text" Value="✈"/>
<Setter Property="Margin" Value="0,3,8,-3"/>
</Style>
<Style x:Key="Unit_124"
BasedOn="{StaticResource DelighterBaseStyle}"
TargetType="TextBlock">
<!-- CoffeeCup -->
<Setter Property="Text" Value="☕"/>
<Setter Property="Margin" Value="0,-1,8,1"/>
</Style>
<Style x:Key="Unit_111"
BasedOn="{StaticResource DelighterBaseStyle}"
TargetType="TextBlock">
<!-- Bathtub -->
<Setter Property="Text" Value="🛀"/>
<Setter Property="Margin" Value="0,2,10,-2"/>
</Style>
<Style x:Key="Unit_125"
BasedOn="{StaticResource DelighterBaseStyle}"
TargetType="TextBlock">
<!-- SwimmingPool -->
<Setter Property="Text" Value="🏊"/>
<Setter Property="Margin" Value="0,2,8,-2"/>
</Style>
<Style x:Key="Unit_113"
BasedOn="{StaticResource DelighterBaseStyle}"
TargetType="TextBlock">
<!-- Snowflake -->
<Setter Property="Text" Value="❄"/>
<Setter Property="Margin" Value="0,3,8,-3"/>
</Style>
<Style x:Key="Unit_133"
BasedOn="{StaticResource Unit_99}"
TargetType="TextBlock">
<!-- Soccer ball -->
<Setter Property="Margin" Value="0,3,8,-3"/>
</Style>
<Style x:Key="Unit_114"
BasedOn="{StaticResource DelighterBaseStyle}"
TargetType="TextBlock">
<!-- Elephant -->
<Setter Property="Text" Value="🐘"/>
<Setter Property="Margin" Value="0,2,9,-2"/>
</Style>
<Style x:Key="Unit_123"
BasedOn="{StaticResource DelighterBaseStyle}"
TargetType="TextBlock">
<!-- Whale -->
<Setter Property="Text" Value="🐳"/>
<Setter Property="Margin" Value="0,1,9,-1"/>
</Style>
</ResourceDictionary>

View file

@ -20,11 +20,11 @@
<Style x:Name="CalculatorBaseStyle" TargetType="local:Calculator">
<Setter Property="Margin" Value="0,0,0,0"/>
</Style>
<!--<Style x:Name="UnitConverterBaseStyle" TargetType="local:UnitConverter">
<Style x:Name="UnitConverterBaseStyle" TargetType="local:UnitConverter">
<Setter Property="Visibility" Value="Collapsed"/>
<Setter Property="IsEnabled" Value="False"/>
<Setter Property="Margin" Value="0,0,0,0"/>
</Style>-->
</Style>
<Style x:Key="AboutFlyoutPresenterStyle" TargetType="FlyoutPresenter">
<Setter Property="IsTabStop" Value="False"/>
<Setter Property="AutomationProperties.AccessibilityView" Value="Raw"/>

View file

@ -80,12 +80,12 @@ namespace CalculatorApp
{
m_graphingCalculator.SetDefaultFocus();
}
// CSHARP_MIGRATION: TODO:
//if (m_converter != null && m_converter.Visibility == Visibility.Visible)
//{
// m_converter.SetDefaultFocus();
//}
if (m_converter != null && m_converter.Visibility == Visibility.Visible)
{
m_converter.SetDefaultFocus();
}
}
public void SetHeaderAutomationName()
{
ViewMode mode = m_model.Mode;
@ -216,12 +216,10 @@ namespace CalculatorApp
m_model.CalculatorViewModel.HistoryVM.AreHistoryShortcutsEnabled = false;
}
// CSHARP_MIGRATION: TODO:
//EnsureConverter();
EnsureConverter();
if (!NavCategory.IsConverterViewMode(previousMode))
{
// CSHARP_MIGRATION: TODO:
//m_converter.AnimateConverter();
m_converter.AnimateConverter();
}
}
@ -397,12 +395,11 @@ namespace CalculatorApp
m_graphingCalculator.IsEnabled = isGraphingCalcViewMode;
}
// CSHARP_MIGRATION: TODO:
//if (m_converter != null)
//{
// m_converter.Visibility = BooleanToVisibilityConverter.Convert(isConverterViewMode);
// m_converter.IsEnabled = isConverterViewMode;
//}
if (m_converter != null)
{
m_converter.Visibility = BooleanToVisibilityConverter.Convert(isConverterViewMode);
m_converter.IsEnabled = isConverterViewMode;
}
}
private void UpdateViewState()
@ -434,9 +431,7 @@ namespace CalculatorApp
private void OnPageLoaded(object sender, RoutedEventArgs args)
{
// CSHARP_MIGRATION: TODO:
//if (!m_converter && !m_calculator && !m_dateCalculator && !m_graphingCalculator)
if (m_calculator == null && m_dateCalculator == null && m_graphingCalculator == null)
if (m_converter == null && m_calculator == null && m_dateCalculator == null && m_graphingCalculator == null)
{
// We have just launched into our default mode (standard calc) so ensure calc is loaded
EnsureCalculator();
@ -541,20 +536,18 @@ namespace CalculatorApp
}
}
// CSHARP_MIGRATION: TODO:
//private void EnsureConverter()
//{
// if (!m_converter)
// {
// // delay loading converter
// m_converter = new CalculatorApp.UnitConverter();
// m_converter.Name = "unitConverter";
// m_converter.DataContext = m_model.ConverterViewModel;
// m_converter.Style = UnitConverterBaseStyle;
// ConverterHolder.Child = m_converter;
// }
//}
private void EnsureConverter()
{
if (m_converter == null)
{
// delay loading converter
m_converter = new CalculatorApp.UnitConverter();
m_converter.Name = "unitConverter";
m_converter.DataContext = m_model.ConverterViewModel;
m_converter.Style = UnitConverterBaseStyle;
ConverterHolder.Child = m_converter;
}
}
private void ShowAboutPage()
{
@ -575,8 +568,7 @@ namespace CalculatorApp
private CalculatorApp.Calculator m_calculator;
private GraphingCalculator m_graphingCalculator;
// CSHARP_MIGRATION: TODO:
//private CalculatorApp.UnitConverter m_converter;
private CalculatorApp.UnitConverter m_converter;
private CalculatorApp.DateCalculator m_dateCalculator;
private CalculatorApp.ViewModel.ApplicationViewModel m_model;
private Windows.UI.ViewManagement.AccessibilitySettings m_accessibilitySettings;

View file

@ -0,0 +1,764 @@
<UserControl x:Class="CalculatorApp.UnitConverter"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:automation="using:CalculatorApp.Common.Automation"
xmlns:common="using:CalculatorApp.Common"
xmlns:controls="using:CalculatorApp.Controls"
xmlns:converters="using:CalculatorApp.Converters"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:CalculatorApp"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:triggers="using:CalculatorApp.Views.StateTriggers"
xmlns:vm="using:CalculatorApp.ViewModel"
d:DesignHeight="658"
d:DesignWidth="830"
DataContextChanged="OnDataContextChanged"
FlowDirection="LeftToRight"
Loaded="OnLoaded"
mc:Ignorable="d">
<UserControl.Resources>
<common:VisibilityNegationConverter x:Name="VisibilityNegationConverter"/>
<common:AlwaysSelectedCollectionViewConverter x:Name="AlwaysSelectedConverter"/>
<common:ValidSelectedItemConverter x:Name="ValidSelectedItemConverter"/>
<converters:BooleanToVisibilityConverter x:Name="BooleanToVisibilityConverter"/>
<converters:BooleanToVisibilityNegationConverter x:Name="BooleanToVisibilityNegationConverter"/>
<automation:NarratorNotifier x:Name="NarratorNotifier" Announcement="{x:Bind Model.Announcement, Mode=OneWay}"/>
<DataTemplate x:Key="UnitTemplate" x:DataType="vm:Unit">
<TextBlock Style="{ThemeResource BodyTextBlockStyle}"
AutomationProperties.Name="{x:Bind AccessibleName}"
Text="{x:Bind Name}"
TextWrapping="NoWrap"/>
</DataTemplate>
<!-- Native bindings can't be use with this template, it will launch an exception when ComboxBox.SelectedItem == null -->
<!-- if you switch between modes when no currencies are available for example) -->
<DataTemplate x:Key="SelectedUnitTemplate">
<TextBlock Style="{ThemeResource BodyTextBlockStyle}"
FontWeight="SemiBold"
AutomationProperties.Name="{Binding AccessibleName, Mode=OneTime, FallbackValue=''}"
Text="{Binding Name, Mode=OneTime, FallbackValue=''}"
TextWrapping="NoWrap"/>
</DataTemplate>
<Style x:Key="ComboStyle" TargetType="ComboBox">
<Setter Property="Padding" Value="12,0,0,0"/>
<Setter Property="MinHeight" Value="32"/>
<Setter Property="Foreground" Value="{ThemeResource SystemControlForegroundBaseHighBrush}"/>
<Setter Property="Background" Value="{ThemeResource SystemControlBackgroundTransparentBrush}"/>
<Setter Property="BorderBrush" Value="{ThemeResource SystemControlForegroundBaseMediumLowBrush}"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="TabNavigation" Value="Once"/>
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled"/>
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
<Setter Property="ScrollViewer.HorizontalScrollMode" Value="Disabled"/>
<Setter Property="ScrollViewer.VerticalScrollMode" Value="Auto"/>
<Setter Property="ScrollViewer.IsVerticalRailEnabled" Value="True"/>
<Setter Property="ScrollViewer.IsDeferredScrollingEnabled" Value="False"/>
<Setter Property="ScrollViewer.BringIntoViewOnFocusChange" Value="True"/>
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="VerticalAlignment" Value="Top"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="IsTextScaleFactorEnabled" Value="True"/>
<Setter Property="UseSystemFocusVisuals" Value="True"/>
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<CarouselPanel/>
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ComboBox">
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="PointerOver">
<VisualState.Setters>
<Setter Target="BackgroundElement.Background" Value="{ThemeResource SystemControlHighlightTransparentBrush}"/>
<Setter Target="SelectedContentPresenter.Foreground" Value="{ThemeResource SystemControlHighlightAltBaseMediumHighBrush}"/>
<Setter Target="DropDownGlyph.Foreground" Value="{ThemeResource SystemControlHighlightAltBaseMediumHighBrush}"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Pressed">
<VisualState.Setters>
<Setter Target="BackgroundElement.Background" Value="{ThemeResource SystemControlHighlightTransparentBrush}"/>
<Setter Target="SelectedContentPresenter.Foreground" Value="{ThemeResource SystemControlHighlightAltBaseMediumBrush}"/>
<Setter Target="DropDownGlyph.Foreground" Value="{ThemeResource SystemControlHighlightAltBaseMediumBrush}"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Disabled"/>
</VisualStateGroup>
<VisualStateGroup x:Name="DropDownStates">
<VisualState x:Name="Opened">
<Storyboard>
<SplitOpenThemeAnimation ClosedTargetName="SelectedContentPresenter"
OffsetFromCenter="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.DropDownOffset}"
OpenedLength="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.DropDownOpenedHeight}"
OpenedTargetName="PopupBorder"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Closed">
<Storyboard>
<SplitCloseThemeAnimation ClosedTargetName="SelectedContentPresenter"
OffsetFromCenter="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.DropDownOffset}"
OpenedLength="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.DropDownOpenedHeight}"
OpenedTargetName="PopupBorder"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Border x:Name="BackgroundElement"
Grid.ColumnSpan="2"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"/>
<!--
This first ContentPresenter must be named "ContentPresenter" because
XAML expects it in the template and has dependencies. It is not used
because we want to style the selected item differently than the items
list but XAML forces the same style. Do not remove
this element.
-->
<ContentPresenter x:Name="ContentPresenter" Opacity="0"/>
<ContentPresenter x:Name="SelectedContentPresenter"
Margin="{TemplateBinding Padding}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
AutomationProperties.AccessibilityView="Raw"
Content="{TemplateBinding SelectedItem}"
ContentTemplate="{StaticResource SelectedUnitTemplate}"
FlowDirection="{TemplateBinding FlowDirection}"/>
<TextBlock x:Name="DropDownGlyph"
Grid.Column="1"
Margin="8,3,12,0"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Foreground="{ThemeResource SystemControlForegroundBaseHighBrush}"
FontFamily="{ThemeResource SymbolThemeFontFamily}"
FontSize="12"
AutomationProperties.AccessibilityView="Raw"
IsHitTestVisible="False"
Text="&#xE0E5;"/>
<Popup x:Name="Popup">
<Border x:Name="PopupBorder"
Margin="0,-1,0,-1"
HorizontalAlignment="Stretch"
Background="{ThemeResource SystemControlBackgroundChromeMediumLowBrush}"
BorderBrush="{ThemeResource SystemControlForegroundChromeHighBrush}"
BorderThickness="{ThemeResource ComboBoxDropdownBorderThickness}">
<ScrollViewer x:Name="ScrollViewer"
MinWidth="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.DropDownContentMinWidth}"
Foreground="{ThemeResource SystemControlForegroundBaseHighBrush}"
AutomationProperties.AccessibilityView="Raw"
BringIntoViewOnFocusChange="{TemplateBinding ScrollViewer.BringIntoViewOnFocusChange}"
HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}"
HorizontalScrollMode="{TemplateBinding ScrollViewer.HorizontalScrollMode}"
IsDeferredScrollingEnabled="{TemplateBinding ScrollViewer.IsDeferredScrollingEnabled}"
IsHorizontalRailEnabled="{TemplateBinding ScrollViewer.IsHorizontalRailEnabled}"
IsVerticalRailEnabled="{TemplateBinding ScrollViewer.IsVerticalRailEnabled}"
VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}"
VerticalScrollMode="{TemplateBinding ScrollViewer.VerticalScrollMode}"
VerticalSnapPointsAlignment="Near"
VerticalSnapPointsType="OptionalSingle"
ZoomMode="Disabled">
<ItemsPresenter/>
</ScrollViewer>
</Border>
</Popup>
</Grid>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="ValueBaseStyle"
BasedOn="{StaticResource CalculationResultStyle}"
TargetType="controls:CalculationResult">
<Setter Property="Background" Value="{ThemeResource SystemControlBackgroundTransparentBrush}"/>
<Setter Property="Foreground" Value="{ThemeResource SystemControlForegroundBaseHighBrush}"/>
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="VerticalContentAlignment" Value="Bottom"/>
<Setter Property="FontWeight" Value="Light"/>
<Setter Property="MinFontSize" Value="{ThemeResource BodyFontSize}"/>
</Style>
<Style x:Key="ValueLargeStyle"
BasedOn="{StaticResource ValueBaseStyle}"
TargetType="controls:CalculationResult">
<Setter Property="MaxFontSize" Value="46"/>
<Setter Property="Margin" Value="-2,0,0,0"/>
<Setter Property="DisplayMargin" Value="0,0,0,12"/>
</Style>
<Style x:Key="ValueMediumStyle"
BasedOn="{StaticResource ValueBaseStyle}"
TargetType="controls:CalculationResult">
<Setter Property="MaxFontSize" Value="34"/>
<Setter Property="Margin" Value="0,0,0,0"/>
<Setter Property="DisplayMargin" Value="0,0,0,4"/>
</Style>
<Style x:Key="CurrencySymbolBaseStyle" TargetType="TextBlock">
<Setter Property="FontWeight" Value="Light"/>
<Setter Property="HorizontalAlignment" Value="Left"/>
<Setter Property="VerticalAlignment" Value="Bottom"/>
<Setter Property="Foreground" Value="{ThemeResource SystemControlPageTextBaseHighBrush}"/>
</Style>
<Style x:Key="CurrencySymbolLargeStyle"
BasedOn="{StaticResource CurrencySymbolBaseStyle}"
TargetType="TextBlock">
<Setter Property="FontSize" Value="32"/>
<Setter Property="Margin" Value="0,0,0,17"/>
</Style>
<Style x:Key="CurrencySymbolMediumStyle"
BasedOn="{StaticResource CurrencySymbolBaseStyle}"
TargetType="TextBlock">
<Setter Property="FontSize" Value="24"/>
<Setter Property="Margin" Value="0,0,0,8"/>
</Style>
<Style x:Key="CurrencySymbolSmallStyle"
BasedOn="{StaticResource CurrencySymbolBaseStyle}"
TargetType="TextBlock">
<Setter Property="FontSize" Value="17"/>
<Setter Property="Margin" Value="0,0,0,7"/>
</Style>
<Style x:Key="ValueContainerStyle" TargetType="Grid">
<Setter Property="AutomationProperties.AccessibilityView" Value="Raw"/>
</Style>
<Storyboard x:Name="AnimationStory">
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="ConverterNumPad" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.ScaleX)">
<EasingDoubleKeyFrame KeyTime="0" Value="0.92">
<EasingDoubleKeyFrame.EasingFunction>
<ExponentialEase EasingMode="EaseOut" Exponent="5"/>
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
<EasingDoubleKeyFrame KeyTime="0:0:0.367" Value="1">
<EasingDoubleKeyFrame.EasingFunction>
<ExponentialEase EasingMode="EaseOut" Exponent="5"/>
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="ConverterNumPad" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.ScaleY)">
<EasingDoubleKeyFrame KeyTime="0" Value="0.92">
<EasingDoubleKeyFrame.EasingFunction>
<ExponentialEase EasingMode="EaseOut" Exponent="5"/>
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
<EasingDoubleKeyFrame KeyTime="0:0:0.367" Value="1">
<EasingDoubleKeyFrame.EasingFunction>
<ExponentialEase EasingMode="EaseOut" Exponent="5"/>
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
<MenuFlyout x:Key="CalculationResultContextMenu">
<MenuFlyoutItem x:Name="CopyMenuItem"
x:Uid="CopyMenuItem"
Click="OnCopyMenuItemClicked"
Icon="Copy"/>
<MenuFlyoutItem x:Name="PasteMenuItem"
x:Uid="PasteMenuItem"
Click="OnPasteMenuItemClicked"
Icon="Paste"/>
</MenuFlyout>
</UserControl.Resources>
<Grid x:Name="UnitConverterRootGrid"
HorizontalAlignment="Stretch"
AutomationProperties.LandmarkType="Main">
<Grid.RowDefinitions>
<RowDefinition x:Name="RowTopNav" Height="{StaticResource HamburgerHeightGridLength}"/>
<RowDefinition x:Name="RowDisplay1"
Height="56*"
MinHeight="56"/>
<RowDefinition x:Name="RowUnit1"
Height="32*"
MinHeight="32"/>
<RowDefinition x:Name="RowDisplay2"
Height="56*"
MinHeight="56"/>
<RowDefinition x:Name="RowUnit2"
Height="32*"
MinHeight="32"/>
<RowDefinition x:Name="RowDltrUnits"
Height="Auto"
MinHeight="48"/>
<RowDefinition x:Name="RowNumPad" Height="272*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="GutterLeft" Width="0"/>
<ColumnDefinition x:Name="ColumnLeft" Width="1*"/>
<ColumnDefinition x:Name="ColumnRight" Width="0"/>
<ColumnDefinition x:Name="GutterRight" Width="0"/>
</Grid.ColumnDefinitions>
<!-- End ConverterNumPad -->
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="Layout">
<VisualState x:Name="PortraitLayout"/>
<VisualState x:Name="LandscapeLayout">
<VisualState.StateTriggers>
<triggers:AspectRatioTrigger ActiveIfEqual="True"
NumeratorAspect="Width"
Source="{x:Bind}"
Threshold="1"/>
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="GutterLeft.Width" Value="48"/>
<Setter Target="GutterRight.Width" Value="48"/>
<Setter Target="ColumnLeft.Width" Value="1*"/>
<Setter Target="ColumnRight.Width" Value="1*"/>
<Setter Target="RowDisplay1.Height" Value="4*"/>
<Setter Target="RowUnit1.Height" Value="2*"/>
<Setter Target="RowDisplay2.Height" Value="4*"/>
<Setter Target="RowUnit2.Height" Value="2*"/>
<Setter Target="RowDltrUnits.Height" Value="2*"/>
<Setter Target="CurrencyLoadingGrid.(Grid.ColumnSpan)" Value="2"/>
<Setter Target="ConverterNumPad.(Grid.Row)" Value="1"/>
<Setter Target="ConverterNumPad.(Grid.RowSpan)" Value="5"/>
<Setter Target="ConverterNumPad.(Grid.Column)" Value="2"/>
<Setter Target="ConverterNumPad.(Grid.ColumnSpan)" Value="2"/>
<Setter Target="SupplementaryResults.VerticalAlignment" Value="Top"/>
<Setter Target="RowNumPad.MinHeight" Value="0"/>
<Setter Target="RowNumPad.Height" Value="0"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="Sizing" CurrentStateChanged="OnVisualStateChanged">
<VisualState x:Name="Wide">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowHeight="768" MinWindowWidth="1280"/>
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="Value1.Style" Value="{ThemeResource ValueLargeStyle}"/>
<Setter Target="Value2.Style" Value="{ThemeResource ValueLargeStyle}"/>
<Setter Target="CurrencySymbol1Block.Style" Value="{ThemeResource CurrencySymbolLargeStyle}"/>
<Setter Target="CurrencySymbol2Block.Style" Value="{ThemeResource CurrencySymbolLargeStyle}"/>
<Setter Target="Units1.Height" Value="44"/>
<Setter Target="Units2.Height" Value="44"/>
<Setter Target="ConverterNegateButton.FontSize" Value="24"/>
<Setter Target="ClearEntryButtonPos0.FontSize" Value="24"/>
<Setter Target="BackSpaceButtonSmall.FontSize" Value="24"/>
<Setter Target="NumberPad.ButtonStyle" Value="{StaticResource NumericButtonStyle46}"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Portrait">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowHeight="1024" MinWindowWidth="640"/>
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="SupplementaryResults.VerticalAlignment" Value="Top"/>
<Setter Target="Value1.Style" Value="{ThemeResource ValueLargeStyle}"/>
<Setter Target="Value2.Style" Value="{ThemeResource ValueLargeStyle}"/>
<Setter Target="CurrencySymbol1Block.Style" Value="{ThemeResource CurrencySymbolLargeStyle}"/>
<Setter Target="CurrencySymbol2Block.Style" Value="{ThemeResource CurrencySymbolLargeStyle}"/>
<Setter Target="Units1.Height" Value="44"/>
<Setter Target="Units2.Height" Value="44"/>
<Setter Target="ConverterNegateButton.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="ClearEntryButtonPos0.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="NumberPad.ButtonStyle" Value="{StaticResource NumericButtonStyle34}"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Wide640">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowHeight="0" MinWindowWidth="640"/>
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="Value1.Style" Value="{ThemeResource ValueLargeStyle}"/>
<Setter Target="Value2.Style" Value="{ThemeResource ValueLargeStyle}"/>
<Setter Target="CurrencySymbol1Block.Style" Value="{ThemeResource CurrencySymbolLargeStyle}"/>
<Setter Target="CurrencySymbol2Block.Style" Value="{ThemeResource CurrencySymbolLargeStyle}"/>
<Setter Target="Units1.Height" Value="44"/>
<Setter Target="Units2.Height" Value="44"/>
<Setter Target="ConverterNegateButton.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="ClearEntryButtonPos0.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="BackSpaceButtonSmall.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="NumberPad.ButtonStyle" Value="{StaticResource NumericButtonStyle34}"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="MinSizeLayout">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowHeight="{StaticResource AppMinWindowHeight}" MinWindowWidth="{StaticResource AppMinWindowWidth}"/>
</VisualState.StateTriggers>
</VisualState>
<VisualState x:Name="DefaultLayout">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowHeight="0" MinWindowWidth="0"/>
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="ClearEntryButtonPos0.Margin" Value="1"/>
<Setter Target="BackSpaceButtonSmall.Margin" Value="1"/>
<Setter Target="ConverterNegateButton.Margin" Value="1"/>
<Setter Target="NumberPad.ButtonStyle" Value="{StaticResource NumericButtonStyle18}"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="CurrencyTimestampStates">
<VisualState x:Name="DefaultTimestamp">
<VisualState.Setters>
<Setter Target="CurrencyTimestampTextBlock.Foreground" Value="{ThemeResource SystemControlPageTextBaseHighBrush}"/>
<Setter Target="CurrencyTimestampTextBlock.FontWeight" Value="Normal"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="WeekOldTimestamp">
<VisualState.Setters>
<Setter Target="CurrencyTimestampTextBlock.Foreground" Value="{ThemeResource AppControlPageTextRedColorBrush}"/>
<Setter Target="CurrencyTimestampTextBlock.FontWeight" Value="SemiBold"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="CurrencySecondaryStatusStates">
<VisualState x:Name="ChargesMayApplyCurrencyStatus">
<VisualState.Setters>
<Setter Target="CurrencySecondaryStatus.Foreground" Value="{ThemeResource AppControlPageTextBaseHighColorBrush}"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="FailedCurrencyStatus">
<VisualState.Setters>
<Setter Target="CurrencySecondaryStatus.Foreground" Value="{ThemeResource AppControlPageTextRedColorBrush}"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="CurrencySymbolStates">
<VisualState x:Name="CurrencySymbolLeftState"/>
<VisualState x:Name="CurrencySymbolRightState">
<VisualState.Setters>
<Setter Target="CurrencySymbol1Block.Padding" Value="0,0,12,0"/>
<Setter Target="CurrencySymbol2Block.Padding" Value="0,0,12,0"/>
<Setter Target="CurrencySymbol1Block.(Grid.Column)" Value="2"/>
<Setter Target="CurrencySymbol2Block.(Grid.Column)" Value="2"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="UnitLoadedStates">
<VisualStateGroup.Transitions>
<VisualTransition From="UnitNotLoadedState" To="UnitLoadedState">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Units1" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="Visible"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Value1Container" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="Visible"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Units2" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="Visible"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Value2Container" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="Visible"/>
</ObjectAnimationUsingKeyFrames>
<DoubleAnimation Duration="0:0:1"
From="0"
Storyboard.TargetName="CurrencyRatioEqualityBlock"
Storyboard.TargetProperty="Opacity"
To="1"/>
<DoubleAnimation Duration="0:0:1"
From="0"
Storyboard.TargetName="CurrencyTimestampTextBlock"
Storyboard.TargetProperty="Opacity"
To="1"/>
<DoubleAnimation Duration="0:0:1"
From="0"
Storyboard.TargetName="Units1"
Storyboard.TargetProperty="Opacity"
To="1"/>
<DoubleAnimation Duration="0:0:1"
From="0"
Storyboard.TargetName="Value1Container"
Storyboard.TargetProperty="Opacity"
To="1"/>
<DoubleAnimation Duration="0:0:1"
From="0"
Storyboard.TargetName="Units2"
Storyboard.TargetProperty="Opacity"
To="1"/>
<DoubleAnimation Duration="0:0:1"
From="0"
Storyboard.TargetName="Value2Container"
Storyboard.TargetProperty="Opacity"
To="1"/>
</Storyboard>
</VisualTransition>
</VisualStateGroup.Transitions>
<VisualState x:Name="UnitNotLoadedState">
<VisualState.Setters>
<Setter Target="CurrencyRatioEqualityBlock.Opacity" Value="0"/>
<Setter Target="CurrencyTimestampTextBlock.Opacity" Value="0"/>
<Setter Target="CurrencyLoadingGrid.Visibility" Value="Visible"/>
<Setter Target="Units1.Visibility" Value="Collapsed"/>
<Setter Target="Value1Container.Visibility" Value="Collapsed"/>
<Setter Target="Units2.Visibility" Value="Collapsed"/>
<Setter Target="Value2Container.Visibility" Value="Collapsed"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="UnitLoadedState"/>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid x:Name="CurrencyLoadingGrid"
Grid.Row="1"
Grid.RowSpan="5"
Grid.Column="0"
Grid.ColumnSpan="4">
<Grid.RowDefinitions>
<RowDefinition Height="10*"/>
<RowDefinition Height="7*"/>
<RowDefinition Height="10*"/>
</Grid.RowDefinitions>
<ProgressRing x:Name="CurrencyLoadingProgressRing"
Grid.Row="1"
Grid.Column="1"
MaxWidth="140"
MaxHeight="140"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
IsActive="False"/>
</Grid>
<Grid x:Name="Value1Container"
Grid.Row="1"
Grid.Column="1"
HorizontalAlignment="{x:Bind FlowDirectionHorizontalAlignment}"
Style="{ThemeResource ValueContainerStyle}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock x:Name="CurrencySymbol1Block"
Grid.Column="0"
Padding="12,0,0,0"
Style="{ThemeResource CurrencySymbolMediumStyle}"
AutomationProperties.AccessibilityView="Raw"
Text="{x:Bind Model.CurrencySymbol1, Mode=OneWay}"
Visibility="{x:Bind Model.CurrencySymbolVisibility, Mode=OneWay}"/>
<controls:CalculationResult x:Name="Value1"
Grid.Column="1"
Style="{ThemeResource ValueMediumStyle}"
AutomationProperties.AutomationId="Value1"
AutomationProperties.Name="{x:Bind Model.Value1AutomationName, Mode=OneWay}"
ContextCanceled="OnContextCanceled"
ContextRequested="OnContextRequested"
DisplayValue="{x:Bind Model.Value1, Mode=OneWay}"
FlowDirection="{x:Bind LayoutDirection}"
IsActive="{Binding Value1Active, Mode=TwoWay}"
KeyDown="OnValueKeyDown"
Selected="OnValueSelected"
TabIndex="1"/>
</Grid>
<ComboBox x:Name="Units1"
Grid.Row="2"
Grid.Column="1"
HorizontalAlignment="{x:Bind FlowDirectionHorizontalAlignment}"
Style="{ThemeResource ComboStyle}"
AutomationProperties.AutomationId="Units1"
AutomationProperties.Name="{x:Bind Model.Unit1AutomationName, Mode=OneWay}"
DropDownClosed="UpdateDropDownState"
DropDownOpened="UpdateDropDownState"
FlowDirection="{x:Bind LayoutDirection}"
IsEnabledChanged="Units1_IsEnabledChanged"
ItemTemplate="{StaticResource UnitTemplate}"
ItemsSource="{Binding Units, Converter={StaticResource AlwaysSelectedConverter}}"
SelectedItem="{Binding Unit1, Mode=TwoWay, Converter={StaticResource ValidSelectedItemConverter}}"
TabIndex="2"
IsEnabled="{Binding IsDropDownEnabled}"/>
<Grid x:Name="Value2Container"
Grid.Row="3"
Grid.Column="1"
HorizontalAlignment="{x:Bind FlowDirectionHorizontalAlignment}"
Style="{ThemeResource ValueContainerStyle}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock x:Name="CurrencySymbol2Block"
Grid.Column="0"
Padding="12,0,0,0"
Style="{ThemeResource CurrencySymbolMediumStyle}"
AutomationProperties.AccessibilityView="Raw"
Text="{x:Bind Model.CurrencySymbol2, Mode=OneWay}"
Visibility="{x:Bind Model.CurrencySymbolVisibility, Mode=OneWay}"/>
<controls:CalculationResult x:Name="Value2"
Grid.Column="1"
Style="{ThemeResource ValueMediumStyle}"
AutomationProperties.AutomationId="Value2"
AutomationProperties.LiveSetting="Polite"
AutomationProperties.Name="{x:Bind Model.Value2AutomationName, Mode=OneWay}"
ContextCanceled="OnContextCanceled"
ContextRequested="OnContextRequested"
DisplayValue="{x:Bind Model.Value2, Mode=OneWay}"
FlowDirection="{x:Bind LayoutDirection}"
IsActive="{Binding Value2Active, Mode=TwoWay}"
KeyDown="OnValueKeyDown"
Selected="OnValueSelected"
TabIndex="3"/>
</Grid>
<ComboBox x:Name="Units2"
Grid.Row="4"
Grid.Column="1"
HorizontalAlignment="{x:Bind FlowDirectionHorizontalAlignment}"
Style="{ThemeResource ComboStyle}"
AutomationProperties.AutomationId="Units2"
AutomationProperties.Name="{x:Bind Model.Unit2AutomationName, Mode=OneWay}"
DropDownClosed="UpdateDropDownState"
DropDownOpened="UpdateDropDownState"
FlowDirection="{x:Bind LayoutDirection}"
ItemTemplate="{StaticResource UnitTemplate}"
ItemsSource="{Binding Units, Converter={StaticResource AlwaysSelectedConverter}}"
SelectedItem="{Binding Unit2, Mode=TwoWay, Converter={StaticResource ValidSelectedItemConverter}}"
TabIndex="4"
IsEnabled="{Binding IsDropDownEnabled}"/>
<StackPanel x:Name="SupplementaryResultsPanelInGrid"
Grid.Row="5"
Grid.Column="1"
MinHeight="48"
Padding="12,0,6,0"
HorizontalAlignment="{x:Bind FlowDirectionHorizontalAlignment}"
VerticalAlignment="Top"
FlowDirection="{x:Bind LayoutDirection}"
SizeChanged="SupplementaryResultsPanelInGrid_SizeChanged">
<local:SupplementaryResults x:Name="SupplementaryResults"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Results="{x:Bind Model.SupplementaryResults, Mode=OneWay}"
Visibility="{x:Bind Model.SupplementaryVisibility, Mode=OneWay}"/>
<StackPanel Visibility="{x:Bind Model.IsCurrencyCurrentCategory, Mode=OneWay, Converter={StaticResource BooleanToVisibilityConverter}}">
<!-- Currency Ratio Equality -->
<TextBlock x:Name="CurrencyRatioEqualityBlock"
Style="{ThemeResource CaptionTextBlockStyle}"
Foreground="{ThemeResource SystemControlPageTextBaseHighBrush}"
AutomationProperties.Name="{x:Bind Model.CurrencyRatioEqualityAutomationName, Mode=OneWay}"
Text="{x:Bind Model.CurrencyRatioEquality, Mode=OneWay}"/>
<!-- Currency Timestamp -->
<TextBlock x:Name="CurrencyTimestampTextBlock"
Style="{ThemeResource CaptionTextBlockStyle}"
Text="{x:Bind Model.CurrencyTimestamp, Mode=OneWay}"/>
<!-- Currency Refresh button and additional status text -->
<ContentControl x:Name="CurrencyRefreshBlockControl"
IsTabStop="False"
TabIndex="5"
Visibility="Collapsed">
<StackPanel Orientation="Horizontal">
<HyperlinkButton x:Name="CurrencyRefreshBlock"
x:Uid="RefreshButtonText"
Foreground="{ThemeResource SystemControlHyperlinkBaseHighBrush}"
Click="CurrencyRefreshButton_Click"/>
<TextBlock Margin="3,7,0,0" Style="{ThemeResource CaptionTextBlockStyle}">
<Run x:Name="CurrencySecondaryStatus"
FontWeight="SemiBold"
Text=""/>
</TextBlock>
</StackPanel>
</ContentControl>
<!-- Offline TextBlock -->
<ContentControl x:Name="OfflineBlock"
IsTabStop="False"
TabIndex="5"
Visibility="Collapsed">
<TextBlock Style="{ThemeResource CaptionTextBlockStyle}"
Foreground="{ThemeResource SystemControlPageTextBaseHighBrush}"
AutomationProperties.AccessibilityView="Raw">
<Run x:Name="OfflineRunBeforeLink"/>
<Hyperlink NavigateUri="ms-settings:network-status">
<Run x:Name="OfflineRunLink"/>
</Hyperlink>
<Run x:Name="OfflineRunAfterLink"/>
</TextBlock>
</ContentControl>
</StackPanel>
</StackPanel>
<Grid x:Name="ConverterNumPad"
Grid.Row="6"
Grid.Column="1"
Margin="3,0,3,3"
FlowDirection="LeftToRight"
RenderTransformOrigin="0.5,0.5"
XYFocusKeyboardNavigation="Enabled">
<Grid.RenderTransform>
<CompositeTransform/>
</Grid.RenderTransform>
<Grid.RowDefinitions>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>
<Grid x:Uid="DisplayControls"
Grid.Row="0"
Grid.Column="1"
Grid.ColumnSpan="2"
AutomationProperties.HeadingLevel="Level1">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<controls:CalculatorButton x:Name="ClearEntryButtonPos0"
x:Uid="clearEntryButton"
HorizontalAlignment="Stretch"
Style="{StaticResource OperatorButtonStyle}"
FontSize="16"
ButtonId="Clear"
Content="CE"
TabIndex="7"/>
<controls:CalculatorButton x:Name="BackSpaceButtonSmall"
x:Uid="backSpaceButton"
Grid.Column="1"
Style="{StaticResource SymbolOperatorButtonStyle}"
FontFamily="{ThemeResource SymbolThemeFontFamily}"
FontSize="16"
ButtonId="Backspace"
Content="&#xE750;"
TabIndex="8"/>
</Grid>
<local:NumberPad x:Name="NumberPad"
x:Uid="NumberPad"
Grid.Row="1"
Grid.RowSpan="4"
Grid.Column="0"
Grid.ColumnSpan="3"
VerticalAlignment="Stretch"
AutomationProperties.HeadingLevel="Level1"
ButtonStyle="{StaticResource NumericButtonStyle24}"
TabIndex="10"
TabNavigation="Local"/>
<controls:CalculatorButton x:Name="ConverterNegateButton"
x:Uid="converterNegateButton"
Grid.Row="4"
Grid.Column="0"
Style="{StaticResource SymbolOperatorKeypadButtonStyle}"
FontSize="16"
ButtonId="Negate"
Content="&#xF898;"
TabIndex="6"
Visibility="{x:Bind Model.CurrentCategory.NegateVisibility, Mode=OneWay}"/>
</Grid>
<!-- End ConverterNumPad -->
</Grid>
</UserControl>

View file

@ -0,0 +1,386 @@
using CalculatorApp.Common;
using CalculatorApp.Controls;
using CalculatorApp.ViewModel;
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Threading.Tasks;
using Windows.Foundation;
using Windows.System;
using Windows.UI.ViewManagement;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Automation;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Input;
// The User Control item template is documented at https://go.microsoft.com/fwlink/?LinkId=234236
namespace CalculatorApp
{
class Activatable : ViewModel.IActivatable
{
public Activatable(Func<bool> getter, Action<bool> setter)
{
m_getter = getter;
m_setter = setter;
}
public bool IsActive
{
get => m_getter();
set => m_setter(value);
}
private Func<bool> m_getter;
private Action<bool> m_setter;
}
public sealed partial class UnitConverter : UserControl
{
public UnitConverter()
{
this.InitializeComponent();
}
public Windows.UI.Xaml.HorizontalAlignment FlowDirectionHorizontalAlignment
{
get => this.m_FlowDirectionHorizontalAlignment;
}
private Windows.UI.Xaml.HorizontalAlignment m_FlowDirectionHorizontalAlignment;
public void AnimateConverter()
{
if (uiSettings.Value.AnimationsEnabled)
{
AnimationStory.Begin();
}
}
public CalculatorApp.ViewModel.UnitConverterViewModel Model
{
get => (CalculatorApp.ViewModel.UnitConverterViewModel)this.DataContext;
}
public Windows.UI.Xaml.FlowDirection LayoutDirection
{
get => this.m_layoutDirection;
}
public void SetDefaultFocus()
{
Control[] focusPrecedence = new Control[] { Value1, CurrencyRefreshBlockControl, OfflineBlock, ClearEntryButtonPos0 };
foreach (Control control in focusPrecedence)
{
if (control.Focus(FocusState.Programmatic))
{
break;
}
}
}
private void OnValueKeyDown(object sender, Windows.UI.Xaml.Input.KeyRoutedEventArgs e)
{
if (e.Key == VirtualKey.Space)
{
OnValueSelected(sender);
}
}
private void OnContextRequested(UIElement sender, ContextRequestedEventArgs e)
{
OnValueSelected(sender);
var requestedElement = ((FrameworkElement)sender);
PasteMenuItem.IsEnabled = CopyPasteManager.HasStringToPaste();
Point point;
if (e.TryGetPosition(requestedElement, out point))
{
m_resultsFlyout.ShowAt(requestedElement, point);
}
else
{
// Not invoked via pointer, so let XAML choose a default location.
m_resultsFlyout.ShowAt(requestedElement);
}
e.Handled = true;
}
private void OnContextCanceled(UIElement sender, RoutedEventArgs e)
{
m_resultsFlyout.Hide();
}
private void OnCopyMenuItemClicked(object sender, RoutedEventArgs e)
{
var calcResult = ((CalculationResult)m_resultsFlyout.Target);
CopyPasteManager.CopyToClipboard(calcResult.GetRawDisplayValue());
}
void OnPasteMenuItemClicked(object sender, RoutedEventArgs e)
{
UnitConverter that = this;
_ = Task.Run(async () =>
{
string pastedString = await CopyPasteManager.GetStringToPaste(Model.Mode, CategoryGroupType.Converter, NumberBase.Unknown, BitLength.BitLengthUnknown);
that.Model.OnPaste(pastedString);
});
}
private void OnValueSelected(object sender)
{
var value = ((CalculationResult)sender);
// update the font size since the font is changed to bold
value.UpdateTextState();
((UnitConverterViewModel)this.DataContext).OnValueActivated(new Activatable(() => value.IsActive, flag => value.IsActive = flag));
}
private void UpdateDropDownState(object sender, object e)
{
((UnitConverterViewModel)this.DataContext).IsDropDownOpen = (Units1.IsDropDownOpen) || (Units2.IsDropDownOpen);
KeyboardShortcutManager.UpdateDropDownState((Units1.IsDropDownOpen) || (Units2.IsDropDownOpen));
}
private void OnLoaded(object sender, RoutedEventArgs e)
{
}
private void CurrencyRefreshButton_Click(object sender, RoutedEventArgs e)
{
// If IsCurrencyLoadingVisible is true that means CurrencyRefreshButton_Click was recently called
// and is still executing. In this case there is no reason to process the click.
if (!Model.IsCurrencyLoadingVisible)
{
if (Model.NetworkBehavior == NetworkAccessBehavior.OptIn)
{
m_meteredConnectionOverride = true;
}
Model.RefreshCurrencyRatios();
}
}
private void OnPropertyChanged(object sender, PropertyChangedEventArgs e)
{
string propertyName = e.PropertyName;
if (propertyName == UnitConverterViewModel.NetworkBehaviorPropertyName || propertyName == UnitConverterViewModel.CurrencyDataLoadFailedPropertyName)
{
OnNetworkBehaviorChanged();
}
else if (propertyName == UnitConverterViewModel.CurrencyDataIsWeekOldPropertyName)
{
SetCurrencyTimestampFontWeight();
}
else if (
propertyName == UnitConverterViewModel.IsCurrencyLoadingVisiblePropertyName
|| propertyName == UnitConverterViewModel.IsCurrencyCurrentCategoryPropertyName)
{
OnIsDisplayVisibleChanged();
}
}
private void OnDataContextChanged(FrameworkElement sender, DataContextChangedEventArgs args)
{
// CSHARP_MIGRATION: TODO: double check the original code with below migrated code
Model.PropertyChanged -= OnPropertyChanged;
Model.PropertyChanged += OnPropertyChanged;
OnNetworkBehaviorChanged();
}
private void OnIsDisplayVisibleChanged()
{
if (!Model.IsCurrencyCurrentCategory)
{
VisualStateManager.GoToState(this, UnitLoadedState.Name, false);
}
else
{
if (Model.IsCurrencyLoadingVisible)
{
VisualStateManager.GoToState(this, UnitNotLoadedState.Name, false);
StartProgressRingWithDelay();
}
else
{
HideProgressRing();
VisualStateManager.GoToState(this, !string.IsNullOrEmpty(Model.CurrencyTimestamp) ? UnitLoadedState.Name : UnitNotLoadedState.Name, true);
}
}
}
private void Units1_IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
{
if ((Units1.Visibility == Visibility.Visible) && Units1.IsEnabled)
{
SetDefaultFocus();
}
}
private void OnNetworkBehaviorChanged()
{
switch (Model.NetworkBehavior)
{
case NetworkAccessBehavior.Normal:
OnNormalNetworkAccess();
break;
case NetworkAccessBehavior.OptIn:
OnOptInNetworkAccess();
break;
case NetworkAccessBehavior.Offline:
OnOfflineNetworkAccess();
break;
}
}
private void OnNormalNetworkAccess()
{
CurrencyRefreshBlockControl.Visibility = Visibility.Visible;
OfflineBlock.Visibility = Visibility.Collapsed;
if (Model.CurrencyDataLoadFailed)
{
SetFailedToRefreshStatus();
}
else
{
SetNormalCurrencyStatus();
}
}
void OnOptInNetworkAccess()
{
CurrencyRefreshBlockControl.Visibility = Visibility.Visible;
OfflineBlock.Visibility = Visibility.Collapsed;
if (m_meteredConnectionOverride && Model.CurrencyDataLoadFailed)
{
SetFailedToRefreshStatus();
}
else
{
SetChargesMayApplyStatus();
}
}
void OnOfflineNetworkAccess()
{
CurrencyRefreshBlockControl.Visibility = Visibility.Collapsed;
OfflineBlock.Visibility = Visibility.Visible;
}
private void InitializeOfflineStatusTextBlock()
{
var resProvider = AppResourceProvider.GetInstance();
string offlineStatusHyperlinkText = resProvider.GetResourceString("OfflineStatusHyperlinkText");
// The resource string has the 'NetworkSettings' hyperlink wrapped with '%HL%'.
// Break the string and assign pieces appropriately.
const string delimiter = "%HL%";
int delimiterLength = delimiter.Length;
// Find the delimiters.
int firstSplitPosition = offlineStatusHyperlinkText.IndexOf(delimiter);
Debug.Assert(firstSplitPosition != -1);
int secondSplitPosition = offlineStatusHyperlinkText.IndexOf(delimiter, firstSplitPosition + 1);
Debug.Assert(secondSplitPosition != -1);
int hyperlinkTextLength = secondSplitPosition - (firstSplitPosition + delimiterLength);
// Assign pieces.
var offlineStatusTextBeforeHyperlink = offlineStatusHyperlinkText.Substring(0, firstSplitPosition);
var offlineStatusTextLink = offlineStatusHyperlinkText.Substring(firstSplitPosition + delimiterLength, hyperlinkTextLength);
var offlineStatusTextAfterHyperlink = offlineStatusHyperlinkText.Substring(secondSplitPosition + delimiterLength);
OfflineRunBeforeLink.Text = offlineStatusTextBeforeHyperlink;
OfflineRunLink.Text = offlineStatusTextLink;
OfflineRunAfterLink.Text = offlineStatusTextAfterHyperlink;
AutomationProperties.SetName(OfflineBlock, offlineStatusTextBeforeHyperlink + " " + offlineStatusTextLink + " " + offlineStatusTextAfterHyperlink);
}
private void SetNormalCurrencyStatus()
{
CurrencySecondaryStatus.Text = "";
}
private void SetChargesMayApplyStatus()
{
VisualStateManager.GoToState(this, "ChargesMayApplyCurrencyStatus", false);
CurrencySecondaryStatus.Text = m_chargesMayApplyText;
}
private void SetFailedToRefreshStatus()
{
VisualStateManager.GoToState(this, "FailedCurrencyStatus", false);
CurrencySecondaryStatus.Text = m_failedToRefreshText;
}
private void SetCurrencyTimestampFontWeight()
{
if (Model.CurrencyDataIsWeekOld)
{
VisualStateManager.GoToState(this, "WeekOldTimestamp", false);
}
else
{
VisualStateManager.GoToState(this, "DefaultTimestamp", false);
}
}
private void StartProgressRingWithDelay()
{
HideProgressRing();
TimeSpan delay = TimeSpan.FromMilliseconds(500);
m_delayTimer = new DispatcherTimer();
m_delayTimer.Interval = delay;
m_delayTimer.Tick += OnDelayTimerTick;
m_delayTimer.Start();
}
private void OnDelayTimerTick(object sender, object e)
{
CurrencyLoadingProgressRing.IsActive = true;
m_delayTimer.Stop();
}
private void HideProgressRing()
{
if (m_delayTimer != null)
{
m_delayTimer.Stop();
}
CurrencyLoadingProgressRing.IsActive = false;
}
private void SupplementaryResultsPanelInGrid_SizeChanged(object sender, Windows.UI.Xaml.SizeChangedEventArgs e)
{
// We add 0.01 to be sure to not create an infinite loop with SizeChanged events cascading due to float approximation
RowDltrUnits.MinHeight = Math.Max(48.0, e.NewSize.Height + 0.01);
}
private void OnVisualStateChanged(object sender, Windows.UI.Xaml.VisualStateChangedEventArgs e)
{
var mode = NavCategory.Deserialize(Model.CurrentCategory.GetModelCategoryId());
TraceLogger.GetInstance().LogVisualStateChanged(mode, e.NewState.Name, false);
}
private static Lazy<UISettings> uiSettings = new Lazy<UISettings>(true);
private Windows.UI.Xaml.FlowDirection m_layoutDirection;
private Windows.UI.Xaml.Controls.MenuFlyout m_resultsFlyout;
private string m_chargesMayApplyText;
private string m_failedToRefreshText;
private bool m_meteredConnectionOverride;
private Windows.UI.Xaml.DispatcherTimer m_delayTimer;
}
}