Files
GSS2Rework/GSS2/Views/AmineContent/SampleCalibrationView.axaml
T
amkovkov 3cc4d21947 feat: massive rework
1) GSS2.Core:
- strip prefixes in GSS2.Core.Analysis.AmineContent namespace class names
- add IEnumerable<double>.Variance extension
- remake analysis + update database so not needed to store all every file, calibration data also stored in database, also currently capturing images stored in system temporary directory and rewriting every time
2) GSS.UI.Core: AsyncImageRecordViewModel make zoom and pans public
3) GSS:
- remove image-storage-clear command
- remove ResultsView and ResultsViewModel, results presented in analysis
- rework calibration views
- add analysis views
- add text and number fields editors view
- add confirmation view on danger buttons
2026-05-13 12:56:32 +03:00

481 lines
30 KiB
XML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<UserControl
x:Class="GSS2.Views.AmineContent.SampleCalibrationView"
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="using:GSS2.ViewModels.AmineContent"
xmlns:converters="using:GSS2.UI.Core.Converters"
xmlns:avalonia_converters="using:Avalonia.Data.Converters"
xmlns:i="using:Avalonia.Xaml.Interactivity"
xmlns:ia="using:Avalonia.Xaml.Interactions.Custom"
xmlns:controls="using:GSS2.Controls"
xmlns:core="using:GSS2.UI.Core"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
x:DataType="vm:SampleCalibrationViewModel">
<UserControl.Resources>
<converters:NotEqualsConverter x:Key="NotEqualsConverter" />
<converters:EqualsConverter x:Key="EqualsConverter" />
<converters:DateTimeConverter x:Key="DateTimeConverter" />
<SolidColorBrush x:Key="MenuBackground" Color="#00357a" />
<SolidColorBrush x:Key="MenuBorder" Color="#0865b2" />
<SolidColorBrush x:Key="Overlay" Color="#0865b23f" />
<SolidColorBrush x:Key="ButtonBackground" Color="#0865b2" />
<SolidColorBrush x:Key="ButtonDangerBackground" Color="#b20808" />
<SolidColorBrush x:Key="ButtonForeground" Color="#ffffff" />
<SolidColorBrush x:Key="MainBackground" Color="#001e46" />
</UserControl.Resources>
<UserControl.Styles>
<Style Selector="Button">
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="Background" Value="{StaticResource ButtonBackground}" />
<Setter Property="Foreground" Value="{StaticResource ButtonForeground}" />
</Style>
<Style Selector="Button.danger">
<Setter Property="Background" Value="{StaticResource ButtonDangerBackground}" />
</Style>
<Style Selector="Button.vertical">
<Setter Property="MinWidth" Value="40" />
</Style>
<Style Selector="TextBox">
<Setter Property="FontSize" Value="20"/>
</Style>
<Style Selector="TextBox.singleline">
<Setter Property="VerticalContentAlignment" Value="Center" />
</Style>
<Style Selector="TextBox.multiline">
<Setter Property="VerticalContentAlignment" Value="Top" />
<Setter Property="AcceptsReturn" Value="True" />
<Setter Property="TextWrapping" Value="Wrap" />
</Style>
<Style Selector="TextBlock">
<Setter Property="FontSize" Value="20"/>
<Setter Property="VerticalAlignment" Value="Center" />
</Style>
<Style Selector="TextBlock.mini">
<Setter Property="FontSize" Value="16"/>
<Setter Property="Margin" Value="0,0,0,0" />
</Style>
</UserControl.Styles>
<Grid Background="{StaticResource MainBackground}">
<!-- Основная форма -->
<Grid IsEnabled="{Binding !MenuOpened}" ColumnSpacing="5" RowSpacing="5">
<Grid.RowDefinitions>
<RowDefinition Height="*" /> <!-- Главная панель -->
<RowDefinition Height="Auto" /> <!-- Кнопки главной панели -->
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" /> <!-- Удалить -->
<ColumnDefinition Width="*" /> <!-- Сохранить -->
<ColumnDefinition Width="*" /> <!-- К информации/К изображению -->
</Grid.ColumnDefinitions>
<!-- Главная панель -->
<core:SectionPanel Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="3"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
CanScrollBackward="{Binding MainSectionCanScrollBackward}"
CanScrollForward="{Binding MainSectionCanScrollForward}"
ClipToBounds="True"
CurrentIndex="{Binding MainSectionCurrentIndex}"
IsScrolling="{Binding MainSectionIsScrolling}"
Orientation="Vertical">
<!-- Информация -->
<Grid ColumnSpacing="5" RowSpacing="5">
<Grid.RowDefinitions>
<RowDefinition Height="*" /> <!-- Информация -->
<RowDefinition Height="Auto" /> <!-- Кнопки -->
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" /> <!-- Кнопка меню -->
<ColumnDefinition Width="*" /> <!-- Информация -->
<ColumnDefinition Width="*" /> <!-- Информация -->
</Grid.ColumnDefinitions>
<!-- Кнопка меню -->
<Button Grid.Column="0" Grid.Row="0" Grid.RowSpan="3" Classes="vertical" VerticalAlignment="Stretch" Command="{Binding ToggleMenuCommand}">
<TextBlock Text="☰"/>
</Button>
<!-- Информация -->
<core:SectionPanel Grid.Row="0" Grid.Column="1" Grid.ColumnSpan="2"
CanScrollBackward="{Binding InfoSectionCanScrollBackward}"
CanScrollForward="{Binding InfoSectionCanScrollForward}"
ClipToBounds="True"
CurrentIndex="{Binding InfoSectionCurrentIndex}"
Cyclic="True"
IsScrolling="{Binding InfoSectionIsScrolling}"
Orientation="Horizontal">
<!-- ИД / Название пробы / Марка пробы / Дата и время отбора пробы / Место отбора пробы / Масса пробы (кг) -->
<Grid ColumnSpacing="5" RowSpacing="5">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" /> <!-- ИД (подпись) -->
<RowDefinition Height="Auto" /> <!-- ИД (поле) -->
<RowDefinition Height="Auto" /> <!-- Название пробы (подпись) / Марка пробы (подпись) -->
<RowDefinition Height="Auto" /> <!-- Название пробы (поле) / Марка пробы (поле) -->
<RowDefinition Height="Auto" /> <!-- Дата и время отбора пробы (подпись) / Место отбора пробы (подпись) -->
<RowDefinition Height="Auto" /> <!-- Дата и время отбора пробы (поле) / Место отбора пробы (поле) -->
<RowDefinition Height="Auto" /> <!-- Масса пробы (кг) (подпись) -->
<RowDefinition Height="Auto" /> <!-- Масса пробы (кг) (поле) -->
<RowDefinition Height="*" /> <!-- Пустое пространство -->
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" /> <!-- Информация -->
<ColumnDefinition Width="*" /> <!-- Информация -->
</Grid.ColumnDefinitions>
<!-- Информация -->
<!-- ИД (подпись) -->
<TextBlock Grid.Row="0" Grid.ColumnSpan="2" Grid.Column="0" Classes="mini" Text="ИД:" />
<!-- ИД (поле) -->
<TextBox Grid.Row="1" Grid.ColumnSpan="2" Grid.Column="0" Classes="singleline" Text="{Binding EditingRecord.Id}" PlaceholderText="ИД" IsReadOnly="True" />
<!-- Название пробы (подпись) -->
<TextBlock Grid.Row="2" Grid.Column="0" Classes="mini" Text="Название пробы:" />
<!-- Название пробы (поле) -->
<controls:TouchTextBox Grid.Row="3" Grid.Column="0" Classes="singleline" Text="{Binding EditingRecord.SampleName}" PlaceholderText="Название пробы" />
<!-- Марка пробы (подпись) -->
<TextBlock Grid.Row="2" Grid.Column="1" Classes="mini" Text="Марка пробы:" />
<!-- Марка пробы (поле) -->
<controls:TouchTextBox Grid.Row="3" Grid.Column="1" Classes="singleline" Text="{Binding EditingRecord.SampleBrand}" PlaceholderText="Марка пробы" />
<!-- Дата и время отбора пробы (подпись) -->
<TextBlock Grid.Row="4" Grid.Column="0" Classes="mini" Text="Дата и время отбора пробы:" />
<!-- Дата и время отбора пробы (поле) -->
<controls:TouchTextBox Grid.Row="5" Grid.Column="0" Classes="singleline" Text="{Binding EditingRecord.SamplingDateTime, Converter={StaticResource DateTimeConverter}}" PlaceholderText="Дата и время отбора пробы" />
<!-- Место отбора пробы (подпись) -->
<TextBlock Grid.Row="4" Grid.Column="1" Classes="mini" Text="Место отбора пробы:" />
<!-- Место отбора пробы (поле) -->
<controls:TouchTextBox Grid.Row="5" Grid.Column="1" Classes="singleline" Text="{Binding EditingRecord.SamplingPlace}" PlaceholderText="Место отбора пробы" />
<!-- Масса пробы (кг) (подпись) -->
<TextBlock Grid.Row="6" Grid.ColumnSpan="2" Grid.Column="0" Classes="mini" Text="Масса пробы (кг):" />
<!-- Масса пробы (кг) (поле) -->
<controls:TouchNumericUpDown Grid.Row="7" Grid.ColumnSpan="2" Grid.Column="0" Classes="singleline" FormatString="0.0000" Increment="0.0001" Value="{Binding EditingRecord.SampleMass}" PlaceholderText="Масса пробы (кг)" />
</Grid>
<!-- Название используемой кондиционирующей смеси / Содержание аминов в кондиционирующей смеси (%) / Норма расхода кондиционирующей смеси (кг/т | гр/кг) / Фактический расход кондиционирующей смеси (кг/т | гр/кг) -->
<Grid ColumnSpacing="5" RowSpacing="5">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" /> <!-- Название используемой кондиционирующей смеси (подпись) -->
<RowDefinition Height="Auto" /> <!-- Название используемой кондиционирующей смеси (поле) -->
<RowDefinition Height="Auto" /> <!-- Содержание аминов в кондиционирующей смеси (%) (подпись) -->
<RowDefinition Height="Auto" /> <!-- Содержание аминов в кондиционирующей смеси (%) (поле) -->
<RowDefinition Height="Auto" /> <!-- Норма расхода кондиционирующей смеси (кг/т | гр/кг) (подпись) / Фактический расход кондиционирующей смеси (кг/т | гр/кг) (подпись) -->
<RowDefinition Height="Auto" /> <!-- Норма расхода кондиционирующей смеси (кг/т | гр/кг) (поле) / Фактический расход кондиционирующей смеси (кг/т | гр/кг) (поле) -->
<RowDefinition Height="Auto" /> <!-- Измеренное количество масла (кг/т | гр/кг) (подпись) -->
<RowDefinition Height="Auto" /> <!-- Измеренное количество масла (кг/т | гр/кг) (поле) -->
<RowDefinition Height="*" /> <!-- Пустое пространство -->
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" /> <!-- Информация -->
<ColumnDefinition Width="*" /> <!-- Информация -->
</Grid.ColumnDefinitions>
<!-- Информация -->
<!-- Название используемой кондиционирующей смеси (подпись) -->
<TextBlock Grid.Row="0" Grid.ColumnSpan="2" Grid.Column="0" Classes="mini" Text="Название используемой кондиционирующей смеси:" />
<!-- Название используемой кондиционирующей смеси (поле) -->
<controls:TouchTextBox Grid.Row="1" Grid.ColumnSpan="2" Grid.Column="0" Classes="singleline" Text="{Binding EditingRecord.MixtureName}" PlaceholderText="Название используемой кондиционирующей смеси" />
<!-- Содержание люминофоров в кондиционирующей смеси (%) (подпись) -->
<TextBlock Grid.Row="2" Grid.ColumnSpan="2" Grid.Column="0" Classes="mini" Text="Содержание люминофоров в кондиционирующей смеси (%):" />
<!-- Содержание люминофоров в кондиционирующей смеси (%) (поле) -->
<controls:TouchNumericUpDown Grid.Row="3" Grid.ColumnSpan="2" Grid.Column="0" Classes="singleline" FormatString="0.0" Increment="0.1" Value="{Binding EditingRecord.MixtureAmineContent}" PlaceholderText="Содержание люминофоров в кондиционирующей смеси (%)" />
<!-- Норма расхода кондиционирующей смеси (кг/т | гр/кг) (подпись) -->
<TextBlock Grid.Row="4" Grid.Column="0" Classes="mini" Text="Норма расхода (кг/т | гр/кг):" />
<!-- Норма расхода кондиционирующей смеси (кг/т | гр/кг) (поле) -->
<controls:TouchNumericUpDown Grid.Row="5" Grid.Column="0" Classes="singleline" FormatString="0.0000" Increment="0.0001" Value="{Binding EditingRecord.MixtureNormalRate}" PlaceholderText="Норма расхода кондиционирующей смеси (кг/т | гр/кг)" />
<!-- Фактический расход кондиционирующей смеси (кг/т | гр/кг) (подпись) -->
<TextBlock Grid.Row="4" Grid.Column="1" Classes="mini" Text="Фактический расход (кг/т | гр/кг):" />
<!-- Фактический расход кондиционирующей смеси (кг/т | гр/кг) (поле) -->
<controls:TouchNumericUpDown Grid.Row="5" Grid.Column="1" Classes="singleline" FormatString="0.0000" Increment="0.0001" Value="{Binding EditingRecord.MixtureActualRate}" PlaceholderText="Фактический расход кондиционирующей смеси (кг/т | гр/кг)" />
<!-- Измеренное количество кондиционирующей смеси (кг/т | гр/кг) (подпись) -->
<TextBlock Grid.Row="6" Grid.ColumnSpan="2" Grid.Column="0" Classes="mini" Text="Измеренное количество кондиционирующей смеси (кг/т | гр/кг):" />
<!-- Измеренное количество кондиционирующей смеси (кг/т | гр/кг) (поле) -->
<controls:TouchNumericUpDown Grid.Row="7" Grid.ColumnSpan="2" Grid.Column="0" Classes="singleline" FormatString="0.0000" Increment="0.0001" Value="{Binding EditingRecord.MeasuredContent}" PlaceholderText="Измеренное количество кондиционирующей смеси (кг/т | гр/кг)" />
</Grid>
<!-- Дополнительная информация о пробе -->
<Grid ColumnSpacing="5" RowSpacing="5">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" /> <!-- Дополнительная информация о пробе (подпись) -->
<RowDefinition Height="*" /> <!-- Дополнительная информация о пробе (поле) -->
</Grid.RowDefinitions>
<!-- Информация -->
<!-- Дополнительная информация о пробе (подпись) -->
<TextBlock Grid.Row="0" Classes="mini" Text="Дополнительная информация о пробе:" />
<!-- Дополнительная информация о пробе (поле) -->
<controls:TouchTextBox Grid.Row="1" Classes="multiline" Text="{Binding EditingRecord.SampleComment}" PlaceholderText="Дополнительная информация о пробе" />
</Grid>
</core:SectionPanel>
<!-- Кнопка влево -->
<Button Grid.Column="1" Grid.Row="1"
HorizontalAlignment="Stretch" HorizontalContentAlignment="Center" VerticalContentAlignment="Center"
Command="{Binding InfoSectionPreviousCommand}">
<Button.IsEnabled>
<MultiBinding Converter="{x:Static BoolConverters.And}">
<Binding Path="InfoSectionCanScrollBackward" />
<Binding Converter="{x:Static BoolConverters.Not}" Path="InfoSectionIsScrolling" />
</MultiBinding>
</Button.IsEnabled>
<TextBlock Text="◀"/>
</Button>
<!-- Кнопка вправо -->
<Button Grid.Column="2" Grid.Row="1"
HorizontalAlignment="Stretch" HorizontalContentAlignment="Center" VerticalContentAlignment="Center"
Command="{Binding InfoSectionNextCommand}">
<Button.IsEnabled>
<MultiBinding Converter="{x:Static BoolConverters.And}">
<Binding Path="InfoSectionCanScrollForward" />
<Binding Converter="{x:Static BoolConverters.Not}" Path="InfoSectionIsScrolling" />
</MultiBinding>
</Button.IsEnabled>
<TextBlock Text="▶"/>
</Button>
</Grid>
<!-- Изображение -->
<Grid ColumnSpacing="5" RowSpacing="5">
<Grid.RowDefinitions>
<RowDefinition Height="*" /> <!-- Изображение -->
<RowDefinition Height="Auto" /> <!-- Кнопка "Получить изображения" / "Отменить съёмку" -->
</Grid.RowDefinitions>
<!-- Изображение -->
<Grid>
<!-- Изображение -->
<Grid>
<Grid.IsVisible>
<MultiBinding Converter="{x:Static BoolConverters.And}">
<Binding Converter="{x:Static ObjectConverters.IsNotNull}" Path="Image" />
<Binding Converter="{x:Static BoolConverters.Not}" Path="ImagesIsCapturing" />
</MultiBinding>
</Grid.IsVisible>
<!-- Изображение -->
<core:ZoomPanImage HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
ImageSource="{Binding Image.Image}"
Background="Black"
IsVisible="{Binding Image.IsLoading, Converter={x:Static BoolConverters.Not}}" />
<!-- Оверлей загрузки -->
<StackPanel HorizontalAlignment="Stretch" VerticalAlignment="Center" IsVisible="{Binding Image.IsLoading}">
<ProgressBar IsIndeterminate="True" />
<TextBlock HorizontalAlignment="Center" Text="Изображение загружается" />
</StackPanel>
</Grid>
<!-- Оверлей "Изображения отсутствуют" -->
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Text="Изображения отсутствуют">
<TextBlock.IsVisible>
<MultiBinding Converter="{x:Static BoolConverters.And}">
<Binding Converter="{x:Static ObjectConverters.IsNull}" Path="Image" />
<Binding Converter="{x:Static BoolConverters.Not}" Path="ImagesIsCapturing" />
</MultiBinding>
</TextBlock.IsVisible>
</TextBlock>
<!-- Оверлей прогресс -->
<StackPanel HorizontalAlignment="Stretch" VerticalAlignment="Center" IsVisible="{Binding ImagesIsCapturing}">
<ProgressBar IsIndeterminate="True" />
<TextBlock HorizontalAlignment="Center" Text="{Binding ImagesCapturingProgress}" />
</StackPanel>
</Grid>
<!-- Кнопка "Получить изображения" -->
<Button Grid.Row="1"
HorizontalAlignment="Stretch"
Command="{Binding CaptureImageCommand}"
IsVisible="{Binding CaptureImagesTask, Converter={x:Static ObjectConverters.IsNull}}">
<TextBlock Text="Получить изображения"/>
</Button>
<!-- Кнопка "Отменить съёмку" -->
<Button Grid.Row="1"
HorizontalAlignment="Stretch"
Command="{Binding CancelImageCapturingCommand}"
IsVisible="{Binding CaptureImagesTask, Converter={x:Static ObjectConverters.IsNotNull}}">
<TextBlock Text="Отменить съёмку"/>
</Button>
</Grid>
</core:SectionPanel>
<!-- Кнопки главной панели -->
<!-- Удалить -->
<Button Grid.Row="1" Grid.Column="0" HorizontalAlignment="Stretch" Classes="danger" Command="{Binding DeleteRecordCommand}">
<TextBlock Text="Удалить"/>
</Button>
<!-- Сохранить -->
<Button Grid.Row="1" Grid.Column="1" HorizontalAlignment="Stretch" Command="{Binding SaveRecordCommand}" Content="Сохранить">
<TextBlock Text="Сохранить"/>
</Button>
<!-- К информации -->
<Button Grid.Row="1" Grid.Column="2"
HorizontalAlignment="Stretch"
Command="{Binding SwitchMainSectionCommand}"
Content="К информации"
IsVisible="{Binding MainSectionCurrentIndex, Converter={StaticResource EqualsConverter}, ConverterParameter=1}">
<TextBlock Text="К информации"/>
<Button.IsEnabled>
<MultiBinding Converter="{x:Static BoolConverters.And}">
<Binding Path="MainSectionCanScrollBackward" />
<Binding Converter="{x:Static BoolConverters.Not}" Path="MainSectionIsScrolling" />
</MultiBinding>
</Button.IsEnabled>
</Button>
<!-- К изображению -->
<Button Grid.Row="1" Grid.Column="2"
HorizontalAlignment="Stretch"
Command="{Binding SwitchMainSectionCommand}"
Content="К изображению"
IsVisible="{Binding MainSectionCurrentIndex, Converter={StaticResource EqualsConverter}, ConverterParameter=0}">
<TextBlock Text="К изображению"/>
<Button.IsEnabled>
<MultiBinding Converter="{x:Static BoolConverters.And}">
<Binding Path="MainSectionCanScrollForward" />
<Binding Converter="{x:Static BoolConverters.Not}" Path="MainSectionIsScrolling" />
</MultiBinding>
</Button.IsEnabled>
</Button>
</Grid>
<!-- Полупрозрачный оверлей -->
<Border Background="{StaticResource Overlay}" IsEnabled="{Binding MenuOpened}" IsVisible="{Binding MenuOpened}">
<Interaction.Behaviors>
<TappedTrigger>
<InvokeCommandAction Command="{Binding CloseMenuCommand}" />
</TappedTrigger>
</Interaction.Behaviors>
</Border>
<!-- Выезжающая боковая панель -->
<Border HorizontalAlignment="Left"
Background="{StaticResource MenuBackground}" BorderBrush="{StaticResource MenuBorder}" BorderThickness="0,0,1,0"
IsEnabled="{Binding MenuOpened}" IsVisible="{Binding MenuOpened}">
<Border.Transitions>
<Transitions>
<TransformOperationsTransition Property="RenderTransform" Duration="0:0:0.25" />
</Transitions>
</Border.Transitions>
<Interaction.Behaviors>
<DataTriggerBehavior Binding="{Binding MenuOpened}" ComparisonCondition="Equal" Value="True">
<ChangePropertyAction PropertyName="RenderTransform" Value="translateX(0px)" />
</DataTriggerBehavior>
<DataTriggerBehavior Binding="{Binding MenuOpened}" ComparisonCondition="Equal" Value="False">
<ChangePropertyAction PropertyName="RenderTransform" Value="translateX(-320px)" />
</DataTriggerBehavior>
</Interaction.Behaviors>
<!-- Содержимое меню -->
<Grid RowSpacing="10" Margin="10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Button Grid.Row="0" MinWidth="200" HorizontalAlignment="Stretch" Command="{Binding CreateRecordCommand}">
<TextBlock Text="Новая запись"/>
</Button>
<ListBox Grid.Row="1" Background="{StaticResource MenuBackground}" ItemsSource="{Binding Records}" SelectedItem="{Binding SelectedRecord}">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.Styles>
<Style Selector="ListBoxItem">
<Setter Property="Background" Value="{StaticResource ButtonBackground}" />
</Style>
<Style Selector="ListBoxItem:selected /template/ ContentPresenter">
<Setter Property="Background" Value="{StaticResource MainBackground}" />
</Style>
<Style Selector="ListBoxItem:pointerover /template/ ContentPresenter">
<Setter Property="Background" Value="{StaticResource MainBackground}" />
</Style>
</ListBox.Styles>
<ListBox.ItemTemplate>
<DataTemplate>
<Border Margin="3" CornerRadius="5">
<TextBlock Classes="mini" HorizontalAlignment="Center" VerticalAlignment="Center">
<Run Text="{Binding Id, StringFormat='[{0}] '}" />
<Run Text="{Binding SampleName}" />
</TextBlock>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</Border>
</Grid>
</UserControl>