I just redid Rubberduck's About window in XAML:
I do not like my XAML very much. The way I place the StackPanel
for the white pane over two rows, only to provide a margin to keep the copyright text out of it seems very hackish. Just as bad is the way I put the Hyperlink
elements in a textbox (they are not allowed to be placed directly in a StackPanel
because it is not a UIElement
), with the XAML-drawn logo (courtesy of ThunderFrame) inside. Is there a cleaner way to do either of these?
<UserControl x:Class="Rubberduck.UI.About.AboutControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:about="clr-namespace:Rubberduck.UI.About"
mc:Ignorable="d"
d:DesignHeight="350" d:DesignWidth="499"
d:DataContext="{d:DesignInstance {x:Type about:AboutControlViewModel}, IsDesignTimeCreatable=False}">
<UserControl.Resources>
<BitmapImage x:Key="DuckImage" UriSource="../../Resources/RD-AboutWindow.png" />
</UserControl.Resources>
<Grid Background="#F6F6F6F6">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="180" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="55" />
</Grid.RowDefinitions>
<StackPanel HorizontalAlignment="Left"
VerticalAlignment="Top"
Margin="10,10,0,10"
DockPanel.Dock="Top">
<Image Source="{StaticResource DuckImage}"
Margin="0,0,0,5"
Width="170"
HorizontalAlignment="Center" />
<TextBlock HorizontalAlignment="Center">
<Hyperlink Name="WebpageHyperlink"
NavigateUri="http://rubberduckvba.com/"
Command="{Binding UriCommand}"
CommandParameter="{Binding ElementName=WebpageHyperlink, Path=NavigateUri}">http://rubberduckvba.com/</Hyperlink>
</TextBlock>
</StackPanel>
<StackPanel Grid.Column="1"
Grid.Row="0"
Background="White"
Margin="10,10,10,30"
Grid.RowSpan="2">
<TextBlock Margin="10"
Text="{Binding Version}"
FontWeight="Bold"
VerticalAlignment="Top"
HorizontalAlignment="Left"
FontSize="14" />
<Label Content="{Resx ResxName=Rubberduck.UI.RubberduckUI, Key=AboutWindow_AttributionsLabel}"
FontWeight="SemiBold"
FontSize="12"
Margin="5,0,0,0" />
<TextBlock Margin="15,0,0,10"
Text="{Resx ResxName=Rubberduck.UI.RubberduckUI, Key=AboutWindow_AttributionList}"
FontSize="10"/>
<Label Content="{Resx ResxName=Rubberduck.UI.RubberduckUI, Key=AboutWindow_SpecialThanksLabel}"
FontWeight="SemiBold"
FontSize="12"
Margin="5,0,0,0" />
<ScrollViewer Margin="15,0,10,10"
Height="150">
<TextBlock Text="{Resx ResxName=Rubberduck.UI.RubberduckUI, Key=AboutWindow_SpecialThanksList}"
FontSize="10" />
</ScrollViewer>
</StackPanel>
<StackPanel HorizontalAlignment="Left"
Grid.Row="1"
Grid.Column="0"
Grid.ColumnSpan="2"
Margin="10"
Orientation="Horizontal">
<!-- Circle logos created with Ai->XAML Export Plug-In Version 0.2 (PC/64) -->
<!-- By Mike Swanson (http://blog.mikeswanson.com/) -->
<TextBlock>
<Hyperlink Name="GitHubUrl"
NavigateUri="https://github.com/rubberduck-vba/Rubberduck"
Command="{Binding UriCommand}"
CommandParameter="{Binding ElementName=GitHubUrl, Path=NavigateUri}"
TextDecorations="{x:Null}">
<Viewbox Width="35"
Height="35">
<Canvas Width="120"
Height="120"
Background="Transparent">
<Path Fill="Black"
Data=" M 59.996,0.000 C 26.866,0.000 0.000,26.863 0.000,60.003 C 0.000,86.510 17.190,108.999 41.035,116.934 C 44.035,117.484 45.130,115.632 45.130,114.041 C 45.130,112.617 45.078,108.844 45.049,103.837 C 28.359,107.463 24.837,95.794 24.837,95.794 C 22.109,88.862 18.175,87.017 18.175,87.017 C 12.728,83.294 18.588,83.370 18.588,83.370 C 24.609,83.794 27.778,89.553 27.778,89.553 C 33.130,98.722 41.821,96.074 45.240,94.539 C 45.785,90.661 47.335,88.017 49.049,86.517 C 35.725,85.003 21.719,79.856 21.719,56.863 C 21.719,50.313 24.057,44.957 27.895,40.763 C 27.278,39.245 25.219,33.145 28.483,24.884 C 28.483,24.884 33.521,23.271 44.982,31.035 C 49.768,29.704 54.901,29.039 60.003,29.016 C 65.099,29.039 70.232,29.704 75.025,31.035 C 86.479,23.271 91.508,24.884 91.508,24.884 C 94.781,33.145 92.722,39.245 92.105,40.763 C 95.950,44.957 98.272,50.313 98.272,56.863 C 98.272,79.913 84.244,84.985 70.877,86.471 C 73.032,88.323 74.951,91.985 74.951,97.582 C 74.951,105.603 74.877,112.074 74.877,114.041 C 74.877,115.646 75.958,117.513 79.003,116.927 C 102.824,108.977 120.000,86.503 120.000,60.003 C 120.000,26.863 93.134,0.000 59.996,0.000 Z"/>
</Canvas>
</Viewbox>
</Hyperlink>
<Hyperlink Name="TwitterUrl"
NavigateUri="http://www.twitter.com/rubberduckvba"
Command="{Binding UriCommand}"
CommandParameter="{Binding ElementName=TwitterUrl, Path=NavigateUri}"
TextDecorations="{x:Null}">
<Viewbox Margin="10,0,0,0"
Width="35"
Height="35">
<Canvas Width="120"
Height="120"
Background="Transparent">
<Path Fill="Black"
Data="F1 M 92.670,42.747 C 92.702,43.460 92.718,44.177 92.718,44.897 C 92.718,66.860 76.001,92.185 45.431,92.185 C 36.045,92.185 27.310,89.433 19.954,84.718 C 21.255,84.871 22.577,84.950 23.919,84.950 C 31.706,84.950 38.872,82.293 44.560,77.836 C 37.287,77.701 31.149,72.896 29.034,66.293 C 30.049,66.487 31.090,66.591 32.161,66.591 C 33.677,66.591 35.145,66.388 36.540,66.009 C 28.937,64.482 23.208,57.765 23.208,49.712 C 23.208,49.642 23.208,49.572 23.209,49.503 C 25.450,50.748 28.013,51.496 30.737,51.582 C 26.278,48.601 23.344,43.514 23.344,37.748 C 23.344,34.703 24.163,31.848 25.594,29.393 C 33.791,39.448 46.037,46.065 59.850,46.758 C 59.567,45.541 59.420,44.273 59.420,42.970 C 59.420,33.792 66.861,26.351 76.040,26.351 C 80.820,26.351 85.139,28.369 88.171,31.599 C 91.957,30.854 95.514,29.471 98.725,27.566 C 97.484,31.447 94.849,34.704 91.417,36.761 C 94.779,36.359 97.982,35.466 100.963,34.144 C 98.735,37.477 95.917,40.404 92.670,42.747 Z M 60.000,0.000 C 26.863,0.000 0.000,26.863 0.000,60.000 C 0.000,93.137 26.863,120.000 60.000,120.000 C 93.137,120.000 120.000,93.137 120.000,60.000 C 120.000,26.863 93.137,0.000 60.000,0.000 Z"/>
</Canvas>
</Viewbox>
</Hyperlink>
</TextBlock>
</StackPanel>
<TextBlock Grid.Row="1"
Grid.Column="1"
Text="{Resx ResxName=Rubberduck.UI.RubberduckUI, Key=AboutWindow_Copyright}"
FontSize="8"
VerticalAlignment="Bottom"
Margin="10,0,0,10"/>
</Grid>
</UserControl>
I am satisfied with my VM, but here it is for completeness. If anything can be improved, please bring it to my attention.
public class AboutControlViewModel
{
public string Version
{
get
{
var name = Assembly.GetExecutingAssembly().GetName();
return string.Format(RubberduckUI.Rubberduck_AboutBuild, name.Version, name.ProcessorArchitecture);
}
}
private ICommand _uriCommand;
public ICommand UriCommand
{
get
{
if (_uriCommand != null)
{
return _uriCommand;
}
return _uriCommand = new DelegateCommand(uri =>
{
Process.Start(new ProcessStartInfo(((Uri)uri).AbsoluteUri));
});
}
}
}