带有详细信息面板的类似GoogleImages的列表框

时间:2018-10-03 07:35:50

标签: wpf listbox

您将如何设计类似Google图片的组件?

我不确定如何处理选定的每个图像下方显示的详细信息面板。

详细信息面板:
      -在两行图像之间显示。
      -将左右物品固定在适当的位置。

enter image description here

解决方案:

感谢 LittleBit 为该问题提供了非常好的解决方案。根据他的提示,我创建了以下通用组件,其中涉及一些使 LittleBit 解决方案投入生产时最终会遇到的细节。

文件:DetailedList.cs

public class DetailedList : ListBox
{
    #region DetailsTemplate
    public DataTemplate DetailsTemplate
    {
        get { return (DataTemplate)GetValue( DetailsTemplateProperty ); }
        set { SetValue( DetailsTemplateProperty, value ); }
    }

    public static readonly DependencyProperty DetailsTemplateProperty =
        DependencyProperty.Register( nameof( DetailsTemplate ), typeof( DataTemplate ), typeof( DetailedList ) );
    #endregion

    static DetailedList()
    {
        Type ownerType = typeof( DetailedList );

        DefaultStyleKeyProperty.OverrideMetadata( ownerType,
            new FrameworkPropertyMetadata( ownerType ) );

        StyleProperty.OverrideMetadata( ownerType,
            new FrameworkPropertyMetadata( null, ( depObj, baseValue ) =>
            {
                var element = depObj as FrameworkElement;
                if( element != null && baseValue == null )
                    baseValue = element.TryFindResource( ownerType );

                return baseValue;
            } ) );
    }
}

文件:StretchGrid.cs

internal class StretchGrid : Grid
{
    private Expander _expander;

    #region ParentPanel
    public Panel ParentPanel
    {
        get { return (Panel)this.GetValue( ParentPanelProperty ); }
        set { this.SetValue( ParentPanelProperty, value ); }
    }

    public static readonly DependencyProperty ParentPanelProperty = DependencyProperty.Register(
        nameof( ParentPanel ), typeof( Panel ), typeof( StretchGrid ), new PropertyMetadata( null, ParentPanelChanged ) );

    private static void ParentPanelChanged( DependencyObject d, DependencyPropertyChangedEventArgs e )
    {
        var stretchGrid = d as StretchGrid;
        if( stretchGrid == null ) return;

        if( e.NewValue is Panel panel )
            panel.SizeChanged += stretchGrid.UpdateMargins;
    }
    #endregion

    public StretchGrid()
    {
        this.Loaded += StretchGrid_Loaded;
    }

    private void StretchGrid_Loaded( object sender, RoutedEventArgs e )
    {
        _expander = this.FindLogicalParent<Expander>();

        _expander.Expanded += UpdateMargins;
        _expander.SizeChanged += UpdateMargins;

        this.UpdateMargins( null, null );
    }

    private void UpdateMargins( object sender, RoutedEventArgs e )
    {
        if( ParentPanel == null ) return;
        if( _expander == null ) return;

        Point delta = _expander.TranslatePoint( new Point( 0d, 0d ), ParentPanel );

        //Create negative Margin to allow the Grid to be rendered outside of the Boundaries (full row under the item)
        this.Margin = new Thickness( -delta.X, 0, delta.X + _expander.ActualWidth - ParentPanel.ActualWidth, 0 );
    }
}

文件:DetailedList.xaml

 <Style x:Key="{x:Type cc:DetailedList}" TargetType="{x:Type cc:DetailedList}"
       BasedOn="{StaticResource {x:Type ListBox}}">

    <Style.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="NoButtonExpander.xaml"/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Style.Resources>

    <Setter Property="Grid.IsSharedSizeScope" Value="True"/>
    <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled"/>
    <Setter Property="SelectionMode" Value="Single"/>

    <Setter Property="ItemsPanel">
        <Setter.Value>
            <ItemsPanelTemplate>
                <WrapPanel Width="{Binding ActualWidth, RelativeSource={RelativeSource AncestorType={x:Type cc:DetailedList}}}" 
                           Tag="{Binding RelativeSource={RelativeSource Self}}" />
            </ItemsPanelTemplate>
        </Setter.Value>
    </Setter>

    <Setter Property="ItemContainerStyle">
        <Setter.Value>
            <Style TargetType="{x:Type ListBoxItem}">
                <Setter Property="FocusVisualStyle" Value="{x:Null}"/>
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type ListBoxItem}">

                            <Border Name="Border" SnapsToDevicePixels="True">
                                <Expander Style="{StaticResource NoButtonExpander}" VerticalAlignment="Top"
                                      IsExpanded="{Binding IsSelected, RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}}" 
                                      Width="{Binding ActualWidth, RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}}">

                                    <Expander.Header>
                                        <Grid>
                                            <Grid.RowDefinitions>
                                                <RowDefinition SharedSizeGroup="A"/>
                                            </Grid.RowDefinitions>

                                            <ContentPresenter Grid.Row="0"/>
                                        </Grid>
                                    </Expander.Header>

                                    <cc:StretchGrid ParentWrapPanel="{Binding Path=Tag, 
                                        RelativeSource={RelativeSource AncestorType={x:Type WrapPanel}}}">

                                        <ContentPresenter ContentTemplate="{Binding DetailsTemplate, 
                                            RelativeSource={RelativeSource AncestorType={x:Type cc:DetailedList}}}"/>

                                    </cc:StretchGrid>
                                </Expander>
                            </Border>

                            <ControlTemplate.Triggers>
                                <Trigger Property="IsSelected" Value="True">
                                    <Setter TargetName="Border" Property="Background"
                                            Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
                                </Trigger>
                            </ControlTemplate.Triggers>

                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </Setter.Value>
    </Setter>
</Style>

文件:NoButtonExpander.xaml

<Style x:Key="ExpanderRightHeaderStyle" TargetType="{x:Type ToggleButton}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ToggleButton}">
                <Border Padding="{TemplateBinding Padding}">
                    <Grid Background="Transparent" SnapsToDevicePixels="False">
                        <ContentPresenter HorizontalAlignment="Center" Margin="0,4,0,0" Grid.Row="1" RecognizesAccessKey="True" SnapsToDevicePixels="True" VerticalAlignment="Top"/>
                    </Grid>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

<Style x:Key="ExpanderUpHeaderStyle" TargetType="{x:Type ToggleButton}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ToggleButton}">
                <Border Padding="{TemplateBinding Padding}">
                    <Grid Background="Transparent" SnapsToDevicePixels="False">
                        <ContentPresenter Grid.Column="1" HorizontalAlignment="Left" Margin="4,0,0,0" RecognizesAccessKey="True" SnapsToDevicePixels="True" VerticalAlignment="Center"/>
                    </Grid>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

<Style x:Key="ExpanderLeftHeaderStyle" TargetType="{x:Type ToggleButton}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ToggleButton}">
                <Border Padding="{TemplateBinding Padding}">
                    <Grid Background="Transparent" SnapsToDevicePixels="False">
                        <ContentPresenter HorizontalAlignment="Center" Margin="0,4,0,0" Grid.Row="1" RecognizesAccessKey="True" SnapsToDevicePixels="True" VerticalAlignment="Top"/>
                    </Grid>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

<Style x:Key="ExpanderHeaderFocusVisual">
    <Setter Property="Control.Template">
        <Setter.Value>
            <ControlTemplate>
                <Border>
                    <Rectangle Margin="0" SnapsToDevicePixels="true" Stroke="Black" StrokeThickness="1" StrokeDashArray="1 2"/>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

<Style x:Key="ExpanderDownHeaderStyle" TargetType="{x:Type ToggleButton}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ToggleButton}">
                <Border Padding="{TemplateBinding Padding}">
                    <Grid Background="Transparent" SnapsToDevicePixels="False">
                        <ContentPresenter Grid.Column="1" HorizontalAlignment="Left" Margin="4,0,0,0" RecognizesAccessKey="True" SnapsToDevicePixels="True" VerticalAlignment="Center"/>
                    </Grid>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

<Style x:Key="NoButtonExpander" TargetType="{x:Type Expander}">
    <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
    <Setter Property="Background" Value="Transparent"/>
    <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
    <Setter Property="VerticalContentAlignment" Value="Stretch"/>
    <Setter Property="BorderBrush" Value="Transparent"/>
    <Setter Property="BorderThickness" Value="1"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Expander}">
                <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" CornerRadius="3" SnapsToDevicePixels="true">
                    <DockPanel>
                        <ToggleButton x:Name="HeaderSite" ContentTemplate="{TemplateBinding HeaderTemplate}" ContentTemplateSelector="{TemplateBinding HeaderTemplateSelector}" Content="{TemplateBinding Header}" DockPanel.Dock="Top" Foreground="{TemplateBinding Foreground}" FontWeight="{TemplateBinding FontWeight}" FocusVisualStyle="{StaticResource ExpanderHeaderFocusVisual}" FontStyle="{TemplateBinding FontStyle}" FontStretch="{TemplateBinding FontStretch}" FontSize="{TemplateBinding FontSize}" FontFamily="{TemplateBinding FontFamily}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" IsChecked="{Binding IsExpanded, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" Margin="1" MinWidth="0" MinHeight="0" Padding="{TemplateBinding Padding}" Style="{StaticResource ExpanderDownHeaderStyle}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
                        <ContentPresenter x:Name="ExpandSite" DockPanel.Dock="Bottom" Focusable="false" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" Visibility="Collapsed" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                    </DockPanel>
                </Border>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsExpanded" Value="true">
                        <Setter Property="Visibility" TargetName="ExpandSite" Value="Visible"/>
                    </Trigger>
                    <Trigger Property="ExpandDirection" Value="Right">
                        <Setter Property="DockPanel.Dock" TargetName="ExpandSite" Value="Right"/>
                        <Setter Property="DockPanel.Dock" TargetName="HeaderSite" Value="Left"/>
                        <Setter Property="Style" TargetName="HeaderSite" Value="{StaticResource ExpanderRightHeaderStyle}"/>
                    </Trigger>
                    <Trigger Property="ExpandDirection" Value="Up">
                        <Setter Property="DockPanel.Dock" TargetName="ExpandSite" Value="Top"/>
                        <Setter Property="DockPanel.Dock" TargetName="HeaderSite" Value="Bottom"/>
                        <Setter Property="Style" TargetName="HeaderSite" Value="{StaticResource ExpanderUpHeaderStyle}"/>
                    </Trigger>
                    <Trigger Property="ExpandDirection" Value="Left">
                        <Setter Property="DockPanel.Dock" TargetName="ExpandSite" Value="Left"/>
                        <Setter Property="DockPanel.Dock" TargetName="HeaderSite" Value="Right"/>
                        <Setter Property="Style" TargetName="HeaderSite" Value="{StaticResource ExpanderLeftHeaderStyle}"/>
                    </Trigger>
                    <Trigger Property="IsEnabled" Value="false">
                        <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

2 个答案:

答案 0 :(得分:2)

我的方法是使用ListView进行一些修改

  • ItemsPanel中的ListView必须具有'wrap'功能,因此我使用Wrappanel在字段中显示图像预览。
  • ItemContainter中的ListViewItem必须具有两种状态。在Expander之前,图像预览状态和详细视图应该可以解决问题。
  • 图像的详细信息必须在图像下方的整个列中显示。我们需要能够在ListViewItem的边界之外渲染的东西(稍后会介绍)

现在看起来像这样 Image Details messed up 现在,由于边界的原因,图像细节被弄乱了。 Height没问题,因为它只是将下一列向下移动直到适合。问题是Width及其位置(未对齐)。

我创建了一个小的CustomControl,StretchGrid使其Content在整个Column上呈现并保持对齐。此StretchGrid获取到左边界的相对距离,并将其设置为负Margin.Left以正确呈现它。现在看起来像这样(我希望那正是您想要的)。 Image Details properly displayed

现在Style中的ListView

<!-- Image List with Detail -->
<Style x:Key="PicList" TargetType="{x:Type ListView}">
    <!-- Only one Picture can be selected -->
    <Setter Property="SelectionMode" Value="Single"/>

    <!-- Enable Multi-Line with a WrapPanel Around the Items -->
    <Setter Property="ItemsPanel">
        <Setter.Value>
            <ItemsPanelTemplate>
                <WrapPanel Width="{Binding (ListView.ActualWidth),RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListView}}}" Tag="{Binding RelativeSource={RelativeSource Self}}" />
            </ItemsPanelTemplate>
        </Setter.Value>
    </Setter>

    <!-- Override Display area of the Item -->
    <Setter Property="ItemContainerStyle">
        <Setter.Value>
            <Style TargetType="{x:Type ListViewItem}">

                <!-- Define Image Item -->
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type ListBoxItem}">
                            <!-- Use Expander Header as Preview/Thumbnail and display Details below when expanded -->
                            <Expander x:Name="PicThumbnail" Style="{StaticResource NoButtonExpander}" IsExpanded="{Binding (ListViewItem.IsSelected), RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListViewItem}}}" Width="{Binding (ListViewItem.ActualWidth), RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListViewItem}}}">
                                <Expander.Header>
                                    <!-- Thumbnail/Preview Section -->
                                    <StackPanel>
                                        <Image Source="/XAML;component/Assets/Images/Thumb.png" Height="16" Width="16" />
                                        <Label Content="{Binding Name}"/>
                                    </StackPanel>
                                </Expander.Header>
                                <!-- Self stretching Grid (Custom Control) -->
                                <cc:StretchGrid x:Name="PicDetails" Background="LightGray" ParentWrappanel="{Binding Path=Tag, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type WrapPanel}}}">
                                    <!-- Picture Detail Section (quick & dirty designed, replace later) -->
                                    <Image ClipToBounds="False" Source="/XAML;component/Assets/Images/Highres.png" Width="128" Height="128" HorizontalAlignment="Left" Margin="10,0" />
                                    <Rectangle Fill="Black" Height="128" Width="5" HorizontalAlignment="Left"/>
                                    <Rectangle Fill="Black" Height="128" Width="5" HorizontalAlignment="Right"/>
                                    <StackPanel Margin="150,0">
                                        <Label Content="{Binding Name}"/>
                                        <Label Content="Description: Lorem"/>
                                        <Label Content="Category: Ipsum"/>
                                        <Label Content="Owner: Dolor"/>
                                        <Label Content="Size: 5kB"/>
                                    </StackPanel>
                                </cc:StretchGrid>
                            </Expander>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
                <!-- Brings selected element to front, details see edit -->
                <Style.Triggers>
                    <Trigger Property="IsSelected" Value="True">
                        <Setter Property="Panel.ZIndex" Value="1" />
                    </Trigger>
                </Style.Triggers>
            </Style>
        </Setter.Value>
    </Setter>
</Style>

注意:必须添加对StretchGrid的引用。

StretchGrid自定义控件

class StretchGrid : Grid
{
    //Reference for parent expander (used to calculate Grid Margin)
    private Expander m_expander;

    //Property for relativesource Binding to Wrappanel in Style
    public WrapPanel ParentWrappanel
    {
        get { return (WrapPanel)this.GetValue(Wrappanel); }
        set { this.SetValue(Wrappanel, value); }
    }

    //DependencyProperty for RelativeSource Binding to Wrappanel in Style (Note: the Binding is set inside the Style, not here programmatically in PropertyMetaData)
    public static readonly DependencyProperty Wrappanel = DependencyProperty.Register("ParentWrappanel", typeof(WrapPanel), typeof(StretchGrid), new PropertyMetadata(null));

    //Constructor
    public StretchGrid() : base()
    {
        Application.Current.MainWindow.Loaded += Init;
        Application.Current.MainWindow.SizeChanged += UpdateMargins;
    }

    private void Init(object sender, RoutedEventArgs e)
    {
        m_expander = (Expander)this.Parent;                 //Change when xaml markup hirarchy changes
        if(m_expander != null)                              //(or make it similar to the Wrappanel with
        {                                                   //RelativeSource Binding)

            m_expander.Expanded += UpdateMargins;             //Update when expander is expanded
            m_expander.SizeChanged += UpdateMargins;          //Update when the expander changes the Size

            //Update all StretchGrids on Initialization
            UpdateMargins(null, null);
        }
    }

    //Calculate Grid Margin when an according Event is triggered
    private void UpdateMargins(object sender, RoutedEventArgs e)
    {
        if(ParentWrappanel != null)
        {
            Point delta = m_expander.TranslatePoint(new Point(0d, 0d), ParentWrappanel);

            //Create negative Margin to allow the Grid to be rendered outside of the Boundaries (full column under the Image)
            this.Margin = new Thickness(-delta.X, 0, delta.X + m_expander.ActualWidth - ParentWrappanel.ActualWidth, 0);
            //Theese Values arent calculated exavtly, just broad for example purpose
        }
    }
}

将其合并到现有代码中有些棘手。有效的示例可能会有所帮助,并且可以找到HERE

旁注:如果我有更多时间,我会将这些内容打包到更大的自定义控件中,以像普通的UIElement(例如Border)一样使用它。这样可以大大提高可重用性和可用性。


编辑

ListView中的“最新”元素也位于Z索引的顶部,因此它位于扩展后的StretchGrid的上方,并且某些控件无法单击,因为它们位于“后面”下一个ListviewItem

要解决此问题,请添加

<Style.Triggers>
    <Trigger Property="IsSelected" Value="True">
        <Setter Property="Panel.ZIndex" Value="1" />
    </Trigger>
</Style.Triggers>

ListViewItem样式。现在,当它可见时,它将放置在其他控件的顶部。

答案 1 :(得分:0)

这是我到目前为止所做的:-

列出的图片:

enter image description here

单击的图像-将在其下方显示“详细信息”视图:

enter image description here

目前,我不关闭其他详细视图-因此,以下情况对我而言可能发生。 但是,所有这些需要是传播一个已单击其他项目的事件。并关闭所有其他详细信息视图(其mvvm,由bool属性驱动)

enter image description here

================================================ =======

我有一个基本的UserControl,它将以自上而下的方式加载项目:

<Grid>
    <Grid>
        <ScrollViewer>
            <ItemsControl ItemsSource="{Binding GridData, UpdateSourceTrigger=PropertyChanged}">
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <StackPanel Orientation="Vertical"/>
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
            </ItemsControl>
        </ScrollViewer>
    </Grid>
</Grid>

此UserControl本身的每个行(项目)都使用另一个ItemsControl。使图像水平排列。另外,每个项目都有一个“详细信息视图”部分(由图像点击控制可见性的边框)

<UserControl.Resources>
    <ResourceDictionary>
        <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
    </ResourceDictionary>
</UserControl.Resources>
<Grid>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <ItemsControl Grid.Row="0" ItemsSource="{Binding ImagesList, UpdateSourceTrigger=PropertyChanged}">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <StackPanel Orientation="Horizontal"/>
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <Button Margin="5" Command="{Binding DataContext.ItemClickedCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}}}"
                            CommandParameter="{Binding}">
                        <Button.Style>
                            <Style TargetType="Button">
                                <Setter Property="Template">
                                    <Setter.Value>
                                        <ControlTemplate>
                                            <Grid>
                                                <Grid.RowDefinitions>
                                                    <RowDefinition Height="*"/>
                                                    <RowDefinition Height="Auto"/>
                                                </Grid.RowDefinitions>
                                                <Image Grid.Row="0" Source="{Binding Image, UpdateSourceTrigger=PropertyChanged}"/>
                                                <TextBlock Name="DisplayText" Grid.Row="1" HorizontalAlignment="Center" Text="{Binding DisplayText, UpdateSourceTrigger=PropertyChanged}"/>
                                            </Grid>
                                        </ControlTemplate>
                                    </Setter.Value>
                                </Setter>
                            </Style>
                        </Button.Style>
                    </Button>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>

        <Border Margin="2" Grid.Row="1" Background="Black" Padding="10"
                Visibility="{Binding ShowDetailsPanel, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource BooleanToVisibilityConverter}}">
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto"/>
                    <ColumnDefinition Width="*"/>
                </Grid.ColumnDefinitions>
                <Border Grid.Column="0" Background="White" CornerRadius="10">
                    <Image Margin="5" Source="{Binding SelectedImage.Image, UpdateSourceTrigger=PropertyChanged}"/>
                </Border>
                <Grid Grid.Column="1">
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto"/>
                        <RowDefinition Height="Auto"/>
                        <RowDefinition Height="Auto"/>
                        <RowDefinition Height="Auto"/>
                    </Grid.RowDefinitions>
                    <TextBlock Grid.Row="0" Margin="20 20 0 0" FontSize="15"
                               Text="{Binding SelectedImage.ImageName, StringFormat={}Filename: {0}}" Foreground="White"/>
                    <TextBlock Grid.Row="1" Margin="20 20 0 0" FontSize="15"
                               Text="{Binding SelectedImage.Size, StringFormat={}Size: {0} bytes}" Foreground="White"/>
                    <TextBlock Grid.Row="2" Margin="20 20 0 0" FontSize="15"
                               Text="{Binding SelectedImage.Location, StringFormat={}Path: {0}}" Foreground="White"/>
                    <TextBlock Grid.Row="3" Margin="20 20 0 0" FontSize="15"
                               Text="{Binding SelectedImage.CreatedTime, StringFormat={}Last Modified: {0}}" Foreground="White"/>
                </Grid>
            </Grid>
        </Border>
    </Grid>
</Grid>