OmagPHOTO :

- Aggiunta lista lastre che scorre e gestisce migliaia di lastre.
- Miglioramenti e correzioni varie.
This commit is contained in:
Emmanuele Sassi
2018-01-15 10:14:32 +00:00
parent 92daaed21b
commit 53c8d6d934
14 changed files with 512 additions and 49 deletions
@@ -0,0 +1,73 @@
Imports System.ComponentModel
Imports System.Collections.Specialized
Imports System.Windows
Imports System.Windows.Controls.Primitives
Public Class ScrollToTopOnItemsSourceChange
Public Shared ReadOnly ScrollToTopOnItemsSourceChangeProperty As DependencyProperty =
DependencyProperty.RegisterAttached("ScrollToTopOnItemsSourceChange",
GetType(Boolean),
GetType(ScrollToTopOnItemsSourceChange),
New UIPropertyMetadata(False, AddressOf OnScrollToTopOnItemsSourceChangePropertyChanged))
Public Shared Function GetScrollToTopOnItemsSourceChange(ByVal obj As DependencyObject) As Boolean
Return CBool(obj.GetValue(ScrollToTopOnItemsSourceChangeProperty))
End Function
Public Shared Sub SetScrollToTopOnItemsSourceChange(ByVal obj As DependencyObject, ByVal value As Boolean)
obj.SetValue(ScrollToTopOnItemsSourceChangeProperty, value)
End Sub
Private Shared Sub OnScrollToTopOnItemsSourceChangePropertyChanged(ByVal obj As DependencyObject, ByVal e As DependencyPropertyChangedEventArgs)
Dim itemsControl = TryCast(obj, ItemsControl)
If itemsControl Is Nothing Then
Throw New Exception("ScrollToTopOnItemsSourceChange Property must be attached to an ItemsControl based control.")
End If
Dim descriptor As DependencyPropertyDescriptor = DependencyPropertyDescriptor.FromProperty(itemsControl.ItemsSourceProperty, GetType(ItemsControl))
If descriptor IsNot Nothing Then
If CBool(e.NewValue) Then
descriptor.AddValueChanged(itemsControl, AddressOf ItemsSourceChanged)
Else
descriptor.RemoveValueChanged(itemsControl, AddressOf ItemsSourceChanged)
End If
End If
End Sub
Private Shared Sub ItemsSourceChanged(ByVal sender As Object, ByVal e As EventArgs)
Dim itemsControl = TryCast(sender, ItemsControl)
DoScrollToTop(itemsControl)
Dim collection = TryCast(itemsControl.ItemsSource, INotifyCollectionChanged)
If collection IsNot Nothing Then
AddHandler collection.CollectionChanged, Sub(o, args) DoScrollToTop(itemsControl)
End If
End Sub
Private Shared Sub DoScrollToTop(itemsControl As ItemsControl)
Dim eventHandler As EventHandler = Nothing
eventHandler = New EventHandler(Sub()
If (itemsControl.ItemContainerGenerator.Status = GeneratorStatus.ContainersGenerated) Then
Dim scrollViewer As ScrollViewer = GetVisualChild(Of ScrollViewer)(itemsControl)
scrollViewer.ScrollToTop()
RemoveHandler itemsControl.ItemContainerGenerator.StatusChanged, eventHandler
End If
End Sub)
AddHandler itemsControl.ItemContainerGenerator.StatusChanged, eventHandler
End Sub
Private Shared Function GetVisualChild(Of T As Visual)(ByVal parent As DependencyObject) As T
Dim child As T = Nothing
Dim numVisuals As Integer = VisualTreeHelper.GetChildrenCount(parent)
For i = 0 To numVisuals - 1
Dim v = CType(VisualTreeHelper.GetChild(parent, i), Visual)
child = If(TryCast(v, T), GetVisualChild(Of T)(v))
If child IsNot Nothing Then
Exit For
End If
Next
Return child
End Function
End Class
+4 -1
View File
@@ -183,7 +183,10 @@ Public Class MainWindowM
' Leggo nome cartella delle foto
GetMainPrivateProfileString(S_GENERAL, K_PHOTODIR, sDataRoot & "\Data", m_sPhotoDir)
' Creo connessione al Db
ManageDb.ConnectToDb(m_sPhotoDir & "\" & DB_FILENAME)
If Not ManageDb.ConnectToDb(m_sPhotoDir & "\" & DB_FILENAME) Then
MessageBox.Show(EgtMsg(MSG_OMAGPHOTO + 1), EgtMsg(MSG_EGTMSGBOX + 15), MessageBoxButton.OK, MessageBoxImage.Error)
End
End If
' Info su opzioni chiave
EgtOutLog("KeyOptions : " & bKey.ToString() & " " & m_nKeyOptions.ToString() & " " & bProd.ToString())
End Sub
+2
View File
@@ -135,6 +135,7 @@
<DependentUpon>Application.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="AttachedBehaviour\ScrollToTopOnItemsSourceChange.vb" />
<Compile Include="Constants\ConstGen.vb" />
<Compile Include="Constants\ConstIni.vb" />
<Compile Include="Constants\ConstMsg.vb" />
@@ -184,6 +185,7 @@
</Compile>
<Compile Include="Utility\ManageDb.vb" />
<Compile Include="Utility\Map.vb" />
<Compile Include="Utility\VirtualizingTilePanel.vb" />
</ItemGroup>
<ItemGroup>
<Import Include="System.Threading.Tasks" />
+3
View File
@@ -382,6 +382,9 @@ Public Class OptionPanelVM
End Property
Public Sub Remove(ByVal param As Object)
' chiedo conferma
If MessageBox.Show(EgtMsg(MSG_OPTIONPANEL + 5), "", MessageBoxButton.YesNo, MessageBoxImage.Question) <>
MessageBoxResult.Yes Then Return
Dim sImagePath As String = SelSlab.ImagePath
' elimino dal Db
Dim Query As String = "DELETE FROM " & Slab.DB_SLABS & " WHERE " &
+1 -1
View File
@@ -8,7 +8,7 @@
<EgtFloating:EgtFloatingTray x:Name="LEFTTRAY" DockPanel.Dock="Left">
<OmagPHOTO:OptionPanelV DataContext="{StaticResource OptionPanelVM}"
Height="{Binding MaxHeight,ElementName=LEFTTRAY}"/>
Height="{Binding ActualHeight,ElementName=LEFTTRAY}"/>
</EgtFloating:EgtFloatingTray>
<EgtFloating:EgtFloatingTray x:Name="TOPTRAY" DockPanel.Dock="Top">
+34 -23
View File
@@ -1,15 +1,25 @@
<EgtFloating:EgtFloatingManager x:Class="ListPageV"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:EgtFloating="clr-namespace:EgtWPFLib5.EgtFloating;assembly=EgtWPFLib5"
xmlns:EgtWPFLib5="clr-namespace:EgtWPFLib5;assembly=EgtWPFLib5"
xmlns:OmagPHOTO="clr-namespace:OmagPHOTO"
DataContext="{StaticResource ListPageVM}">
<EgtFloating:EgtFloatingManager.Resources>
<OmagPHOTO:ColumnConverter x:Key="ColumnConverter"/>
<sys:Int32 x:Key="Column">6</sys:Int32>
<Style x:Key="SlabListStyle" TargetType="{x:Type ItemsControl}">
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled" />
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ItemsControl}">
<ScrollViewer CanContentScroll="True">
<ItemsPresenter />
</ScrollViewer>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</EgtFloating:EgtFloatingManager.Resources>
<EgtFloating:EgtFloatingTray x:Name="LEFTTRAY" DockPanel.Dock="Left">
@@ -17,41 +27,42 @@
Height="{Binding MaxHeight,ElementName=LEFTTRAY}"/>
</EgtFloating:EgtFloatingTray>
<ItemsControl Name="SlabItemsControl"
ItemsSource="{Binding SlabList}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl Style="{StaticResource SlabListStyle}"
x:Name="SlabItemsControl"
ItemsSource="{Binding SlabList}"
OmagPHOTO:ScrollToTopOnItemsSourceChange.ScrollToTopOnItemsSourceChange="True">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid Width="{Binding ActualWidth, ElementName=SlabItemsControl,
Converter={StaticResource ColumnConverter}}">
<Grid>
<Button Command="{Binding DataContext.SlabBtn_Command,
RelativeSource={RelativeSource AncestorType={x:Type EgtFloating:EgtFloatingManager}}}"
CommandParameter="{Binding}"
ToolTip="{Binding Slab_Tooltip}"
Focusable="False"
Padding="5"
VerticalContentAlignment="Stretch">
RelativeSource={RelativeSource AncestorType={x:Type EgtFloating:EgtFloatingManager}}}"
CommandParameter="{Binding}"
ToolTip="{Binding Slab_Tooltip}"
Focusable="False"
Padding="5"
VerticalContentAlignment="Stretch">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="30"/>
<RowDefinition Height="1*"/>
</Grid.RowDefinitions>
<TextBlock Text="{Binding Id}"
Grid.Row="0"
Margin="0,0,0,5"/>
Grid.Row="0"
Margin="0,0,0,5"/>
<Image Source="{Binding GraphicalImagePath}"
Grid.Row="1"
Stretch="Uniform"/>
Grid.Row="1"
Stretch="Uniform"/>
</Grid>
</Button>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<OmagPHOTO:VirtualizingTilePanel ChildSize="{Binding ChildSize,
RelativeSource={RelativeSource AncestorType={x:Type EgtFloating:EgtFloatingManager}}}"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</EgtFloating:EgtFloatingManager>
+29 -1
View File
@@ -1,3 +1,31 @@
Public Class ListPageV
Imports System.ComponentModel
Public Class ListPageV
Implements INotifyPropertyChanged
Dim count As Integer = 0
Dim ListBox_ScrollViewer As ScrollViewer = Nothing
Public ReadOnly Property ChildSize As Double
Get
If Not IsNumeric(SlabItemsControl.ActualWidth) Then Return 200.0
If Map.refTopCommandBarVM.Search_IsChecked Then
Return (SlabItemsControl.ActualWidth - 22) / 4
Else
Dim x = (SlabItemsControl.ActualWidth - 22) / 6
Return (SlabItemsControl.ActualWidth - 22) / 6
End If
End Get
End Property
Private Sub SlabItemsControl_SizeChanged(sender As Object, e As SizeChangedEventArgs) Handles SlabItemsControl.SizeChanged
NotifyPropertyChanged("ChildSize")
End Sub
Public Event PropertyChanged(sender As Object, e As PropertyChangedEventArgs) Implements INotifyPropertyChanged.PropertyChanged
Public Sub NotifyPropertyChanged(propName As String)
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propName))
End Sub
End Class
+2 -20
View File
@@ -30,7 +30,7 @@ Public Class ListPageVM
#Region "METHODS"
Friend Sub InitListPage()
Map.refProjectVM.SlabList = New ObservableCollection(Of Slab)(ManageDb.ExecuteSlabReaderQuery("SELECT * FROM " & Slab.DB_SLABS))
Map.refProjectVM.SlabList = New ObservableCollection(Of Slab)(ManageDb.ExecuteSlabReaderQuery("SELECT * FROM " & Slab.DB_SLABS & " ORDER BY " & Slab.DB_MATERIAL & ", " & Slab.DB_STATE))
End Sub
#End Region ' METHODS
@@ -59,22 +59,4 @@ Public Class ListPageVM
#End Region ' COMMANDS
End Class
Public Class ColumnConverter
Implements IValueConverter
Public Function Convert(value As Object, targetType As Type, parameter As Object, culture As System.Globalization.CultureInfo) As Object Implements IValueConverter.Convert
Dim dValue As Double = CDbl(value)
If Map.refTopCommandBarVM.Search_IsChecked Then
Return dValue / 4
Else
Return dValue / 6
End If
End Function
Public Function ConvertBack(value As Object, targetType As Type, parameter As Object, culture As System.Globalization.CultureInfo) As Object Implements IValueConverter.ConvertBack
Throw New NotImplementedException
End Function
End Class
End Class
+4 -1
View File
@@ -110,7 +110,8 @@ Public Class ProjectVM
Sub New()
' Creo riferimento a questa classe in Map
Map.SetRefProjectVM(Me)
Map.refTopCommandBarVM.Search_IsChecked = False
' Setto la ricerca come non attiva
Map.refTopCommandBarVM.SetSearch_IsChecked(False)
' Leggo lista materiali da file ini
Dim Index As Integer = 1
Dim sMaterial As String = String.Empty
@@ -124,6 +125,8 @@ Public Class ProjectVM
Dim SearchStateList As New List(Of IdNameStruct)(StateList)
SearchStateList.Insert(0, New IdNameStruct(0, String.Empty))
Map.refSearchPanelVM.SetStateList(SearchStateList)
' Creo lastre random
'AddRandomRows(5000)
End Sub
#End Region ' CONSTRUCTOR
+12
View File
@@ -213,6 +213,17 @@ Public Class Slab
End Set
End Property
Private m_IsLoaded As Boolean
Public Property IsLoaded As Boolean
Get
Return m_IsLoaded
End Get
Set(value As Boolean)
m_IsLoaded = value
NotifyPropertyChanged("IsLoaded")
End Set
End Property
Public ReadOnly Property Slab_Tooltip As String
Get
Dim CurrState As String = String.Empty
@@ -245,6 +256,7 @@ Public Class Slab
m_Thickness = dThickness
m_WarehousePosition = sWarehousePosition
m_AddedDate = Date.Today
m_IsLoaded = False
End Sub
Sub New(SlabReader As SQLiteDataReader)
+3
View File
@@ -7,6 +7,8 @@ Public Class SearchPanelVM
#Region "FIELDS & PROPERTIES"
Friend Event ScrollToTop()
Private m_Id As String
Public Property Id As String
Get
@@ -348,6 +350,7 @@ Public Class SearchPanelVM
Query = Query.TrimEnd(","c, " "c)
End If
Map.refProjectVM.SlabList = New ObservableCollection(Of Slab)(ManageDb.ExecuteSlabReaderQuery(Query))
RaiseEvent ScrollToTop()
End Sub
Private Sub EvalWhere(ByRef bFirst As Boolean, ByRef Query As String)
+5
View File
@@ -31,6 +31,11 @@ Public Class TopCommandBarVM
NotifyPropertyChanged("Search_IsChecked")
End Set
End Property
Friend Sub SetSearch_IsChecked(value As Boolean)
m_Search_IsChecked = value
Map.refSearchPanelVM.SetSearchPanel_Visibility(m_Search_IsChecked)
NotifyPropertyChanged("Search_IsChecked")
End Sub
Private m_Search_IsEnabled As Boolean
Public Property Search_IsEnabled As Boolean
+45 -2
View File
@@ -1,4 +1,5 @@
Imports System.Data.SQLite
Imports System.IO
Imports System.Data.SQLite
Module ManageDb
@@ -22,11 +23,16 @@ Module ManageDb
End Sub
Friend Function ConnectToDb() As Boolean
m_DbConnection = New SQLiteConnection("Data Source = " & Map.refMainWindowVM.MainWindowM.sPhotoDir & "\" & DB_FILENAME & "; Version = 3;")
Dim DbPath As String = Map.refMainWindowVM.MainWindowM.sPhotoDir & "\" & DB_FILENAME
If Not File.Exists(DbPath) Then Return False
m_DbConnection = New SQLiteConnection("Data Source = " & DbPath & "; Version = 3;")
Return Not IsNothing(m_DbConnection)
End Function
Friend Function ConnectToDb(DbPath As String) As Boolean
If Not File.Exists(DbPath) Then
Return False
End If
m_DbConnection = New SQLiteConnection("Data Source = " & DbPath & "; Version = 3;")
Return Not IsNothing(m_DbConnection)
End Function
@@ -69,6 +75,43 @@ Module ManageDb
Return SlabList
End Function
Friend Sub AddRandomRows(nRow As Integer)
Dim ImagePathList() As String = {"c:\EgtData\OmagPHOTO\Data\Lastra15_18.jpg",
"c:\EgtData\OmagPHOTO\Data\Lastra18_10.jpg",
"c:\EgtData\OmagPHOTO\Data\Lastra313.jpg",
"c:\EgtData\OmagPHOTO\Data\Lastra313_b.jpg",
"c:\EgtData\OmagPHOTO\Data\Lastra3138bit.jpg",
"c:\EgtData\OmagPHOTO\Data\Lastra33-18_234.jpg",
"c:\EgtData\OmagPHOTO\Data\Lastra55_33.jpg",
"c:\EgtData\OmagPHOTO\Data\Lastra55-23.jpg",
"c:\EgtData\OmagPHOTO\Data\Prova1.jpg",
"c:\EgtData\OmagPHOTO\Data\Prova2.jpg",
"c:\EgtData\OmagPHOTO\Data\Prova3.jpg",
"c:\EgtData\OmagPHOTO\Data\Prova4.jpg"}
Dim Text As String = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
For i = 0 To nRow
Dim R As New Random()
Dim Name As String = "Lastra" & i
Dim ImagePath As String = ImagePathList(R.Next(0, ImagePathList.Length))
Dim SlabState As String = Map.refOptionPanelVM.StateList(R.Next(0, Map.refOptionPanelVM.StateList.Count)).Id.ToString
Dim Material As String = Map.refOptionPanelVM.MaterialList(R.Next(0, Map.refOptionPanelVM.MaterialList.Count))
Dim SlabThickness As String = (R.Next(200, 700) / 10).ToString
Dim WarehousePosition As String = Text(R.Next(Text.Length)) & R.Next(1, 100) & "." & R.Next(1, 100)
Dim AddedDate As DateTime = DateTime.Now - New TimeSpan(R.Next(0, 730), R.Next(0, 24), R.Next(0, 60), R.Next(0, 60))
' Aggiungo la nuova lastra al Db
Dim Query As String = "INSERT INTO " & Slab.DB_SLABS & " (" & Slab.DB_ID & ", " & Slab.DB_IMAGEPATH & ", " & Slab.DB_STATE & ", " & Slab.DB_PROJASSIGNEDTO & ", " & Slab.DB_MATERIAL & ", " & Slab.DB_THICKNESS & ", " & Slab.DB_WAREHOUSEPOS & ", " & Slab.DB_ADDEDDATE & ")" &
" VALUES ('" & Name & "', " &
"'" & ImagePath & "', " &
SlabState & ", " &
"'" & "C:\EgtData\OmagOFFICE\Progetto" & i & "', " &
"'" & Material & "', " &
SlabThickness & ", " &
"'" & WarehousePosition & "', " &
"Date('" & (String.Format("{0:yyyy-MM-dd}", AddedDate)) & "'))"
ManageDb.ExecuteQuery(Query)
Next
End Sub
#End Region ' METHODS
End Module
+295
View File
@@ -0,0 +1,295 @@
Imports System.Windows.Controls.Primitives
Imports System.Windows.Controls
Imports System.Windows
Imports System.Windows.Media
Imports System
Imports System.Diagnostics
Imports System.Collections.Specialized
Imports System.Windows.Data
Public Class VirtualizingTilePanel
Inherits VirtualizingPanel
Implements IScrollInfo
Public Sub New()
' For use in the IScrollInfo implementation
Me.RenderTransform = _trans
End Sub
Public Shared ReadOnly ChildSizeProperty As DependencyProperty = DependencyProperty.RegisterAttached("ChildSize", GetType(Double), GetType(VirtualizingTilePanel), New FrameworkPropertyMetadata(200.0, FrameworkPropertyMetadataOptions.AffectsMeasure Or FrameworkPropertyMetadataOptions.AffectsArrange))
Public Property ChildSize As Double
Get
Return CDbl(GetValue(ChildSizeProperty))
End Get
Set(ByVal value As Double)
SetValue(ChildSizeProperty, value)
End Set
End Property
Protected Overrides Function MeasureOverride(ByVal availableSize As Size) As Size
UpdateScrollInfo(availableSize)
Dim firstVisibleItemIndex, lastVisibleItemIndex As Integer
GetVisibleRange(firstVisibleItemIndex, lastVisibleItemIndex)
Dim children As UIElementCollection = Me.InternalChildren
Dim generator As IItemContainerGenerator = Me.ItemContainerGenerator
Dim startPos As GeneratorPosition = generator.GeneratorPositionFromIndex(firstVisibleItemIndex)
Dim childIndex As Integer = If((startPos.Offset = 0), startPos.Index, startPos.Index + 1)
Using generator.StartAt(startPos, GeneratorDirection.Forward, True)
Dim itemIndex As Integer = firstVisibleItemIndex
While itemIndex <= lastVisibleItemIndex
Dim newlyRealized As Boolean
Dim child As UIElement = TryCast(generator.GenerateNext(newlyRealized), UIElement)
If newlyRealized Then
If childIndex >= children.Count Then
MyBase.AddInternalChild(child)
Else
MyBase.InsertInternalChild(childIndex, child)
End If
generator.PrepareItemContainer(child)
Else
Debug.Assert(child Is children(childIndex), "Wrong child was generated")
End If
child.Measure(GetChildSize())
System.Threading.Interlocked.Increment(itemIndex)
System.Threading.Interlocked.Increment(childIndex)
End While
End Using
CleanUpItems(firstVisibleItemIndex, lastVisibleItemIndex)
Return availableSize
End Function
Protected Overrides Function ArrangeOverride(ByVal finalSize As Size) As Size
Dim generator As IItemContainerGenerator = Me.ItemContainerGenerator
UpdateScrollInfo(finalSize)
For i As Integer = 0 To Me.Children.Count - 1
Dim child As UIElement = Me.Children(i)
Dim itemIndex As Integer = generator.IndexFromGeneratorPosition(New GeneratorPosition(i, 0))
ArrangeChild(itemIndex, child, finalSize)
Next
Return finalSize
End Function
Private Sub CleanUpItems(ByVal minDesiredGenerated As Integer, ByVal maxDesiredGenerated As Integer)
Dim children As UIElementCollection = Me.InternalChildren
Dim generator As IItemContainerGenerator = Me.ItemContainerGenerator
Dim i As Integer = children.Count - 1
While i >= 0
Dim childGeneratorPos As GeneratorPosition = New GeneratorPosition(i, 0)
Dim itemIndex As Integer = generator.IndexFromGeneratorPosition(childGeneratorPos)
If itemIndex < minDesiredGenerated OrElse itemIndex > maxDesiredGenerated Then
generator.Remove(childGeneratorPos, 1)
RemoveInternalChildRange(i, 1)
End If
i -= 1
End While
End Sub
Protected Overrides Sub OnItemsChanged(ByVal sender As Object, ByVal args As ItemsChangedEventArgs)
Select Case args.Action
Case NotifyCollectionChangedAction.Remove, NotifyCollectionChangedAction.Replace, NotifyCollectionChangedAction.Move
RemoveInternalChildRange(args.Position.Index, args.ItemUICount)
End Select
End Sub
Private Function CalculateExtent(ByVal availableSize As Size, ByVal itemCount As Integer) As Size
Dim childrenPerRow As Integer = CalculateChildrenPerRow(availableSize)
Return New Size(childrenPerRow * Me.ChildSize, Me.ChildSize * Math.Ceiling(CDbl(itemCount) / childrenPerRow))
End Function
Private Sub GetVisibleRange(ByRef firstVisibleItemIndex As Integer, ByRef lastVisibleItemIndex As Integer)
Dim childrenPerRow As Integer = CalculateChildrenPerRow(_extent)
firstVisibleItemIndex = CInt(Math.Floor(_offset.Y / Me.ChildSize)) * childrenPerRow
lastVisibleItemIndex = CInt(Math.Ceiling((_offset.Y + _viewport.Height) / Me.ChildSize)) * childrenPerRow - 1
Dim itemsControl As ItemsControl = itemsControl.GetItemsOwner(Me)
Dim itemCount As Integer = If(itemsControl.HasItems, itemsControl.Items.Count, 0)
If lastVisibleItemIndex >= itemCount Then lastVisibleItemIndex = itemCount - 1
End Sub
Private Function GetChildSize() As Size
Return New Size(Me.ChildSize, Me.ChildSize)
End Function
Private Sub ArrangeChild(ByVal itemIndex As Integer, ByVal child As UIElement, ByVal finalSize As Size)
Dim childrenPerRow As Integer = CalculateChildrenPerRow(finalSize)
Dim row As Integer = itemIndex \ childrenPerRow ' IMPORTANTE L'operatore è di divisione intera, quindi \ NON / che invece arrotonda all'intero pari più vicino!!!!
Dim column As Integer = itemIndex Mod childrenPerRow
child.Arrange(New Rect(column * Me.ChildSize, row * Me.ChildSize, Me.ChildSize, Me.ChildSize))
End Sub
Private Function CalculateChildrenPerRow(ByVal availableSize As Size) As Integer
Dim childrenPerRow As Integer
If availableSize.Width = Double.PositiveInfinity Then childrenPerRow = Me.Children.Count Else childrenPerRow = Math.Max(1, CInt(Math.Floor(availableSize.Width / Me.ChildSize)))
Return childrenPerRow
End Function
Private Sub UpdateScrollInfo(ByVal availableSize As Size)
Dim itemsControl As ItemsControl = itemsControl.GetItemsOwner(Me)
Dim itemCount As Integer = If(itemsControl.HasItems, itemsControl.Items.Count, 0)
Dim extent As Size = CalculateExtent(availableSize, itemCount)
If extent <> _extent Then
_extent = extent
If _owner IsNot Nothing Then _owner.InvalidateScrollInfo()
End If
If availableSize <> _viewport Then
_viewport = availableSize
If _owner IsNot Nothing Then _owner.InvalidateScrollInfo()
End If
End Sub
Public Property ScrollOwner As ScrollViewer Implements IScrollInfo.ScrollOwner
Get
Return _owner
End Get
Set(ByVal value As ScrollViewer)
_owner = value
End Set
End Property
Public Property CanHorizontallyScroll As Boolean Implements IScrollInfo.CanHorizontallyScroll
Get
Return _canHScroll
End Get
Set(ByVal value As Boolean)
_canHScroll = value
End Set
End Property
Public Property CanVerticallyScroll As Boolean Implements IScrollInfo.CanVerticallyScroll
Get
Return _canVScroll
End Get
Set(ByVal value As Boolean)
_canVScroll = value
End Set
End Property
Public ReadOnly Property HorizontalOffset As Double Implements IScrollInfo.HorizontalOffset
Get
Return _offset.X
End Get
End Property
Public ReadOnly Property VerticalOffset As Double Implements IScrollInfo.VerticalOffset
Get
Return _offset.Y
End Get
End Property
Public ReadOnly Property ExtentHeight As Double Implements IScrollInfo.ExtentHeight
Get
Return _extent.Height
End Get
End Property
Public ReadOnly Property ExtentWidth As Double Implements IScrollInfo.ExtentWidth
Get
Return _extent.Width
End Get
End Property
Public ReadOnly Property ViewportHeight As Double Implements IScrollInfo.ViewportHeight
Get
Return _viewport.Height
End Get
End Property
Public ReadOnly Property ViewportWidth As Double Implements IScrollInfo.ViewportWidth
Get
Return _viewport.Width
End Get
End Property
Public Sub LineUp() Implements IScrollInfo.LineUp
SetVerticalOffset(Me.VerticalOffset - 10)
End Sub
Public Sub LineDown() Implements IScrollInfo.LineDown
SetVerticalOffset(Me.VerticalOffset + 10)
End Sub
Public Sub PageUp() Implements IScrollInfo.PageUp
SetVerticalOffset(Me.VerticalOffset - _viewport.Height)
End Sub
Public Sub PageDown() Implements IScrollInfo.PageDown
SetVerticalOffset(Me.VerticalOffset + _viewport.Height)
End Sub
Public Sub MouseWheelUp() Implements IScrollInfo.MouseWheelUp
SetVerticalOffset(Me.VerticalOffset - 50)
End Sub
Public Sub MouseWheelDown() Implements IScrollInfo.MouseWheelDown
SetVerticalOffset(Me.VerticalOffset + 50)
End Sub
Public Sub LineLeft() Implements IScrollInfo.LineLeft
Throw New InvalidOperationException()
End Sub
Public Sub LineRight() Implements IScrollInfo.LineRight
Throw New InvalidOperationException()
End Sub
Public Function MakeVisible(ByVal visual As Visual, ByVal rectangle As Rect) As Rect Implements IScrollInfo.MakeVisible
Return New Rect()
End Function
Public Sub MouseWheelLeft() Implements IScrollInfo.MouseWheelLeft
Throw New InvalidOperationException()
End Sub
Public Sub MouseWheelRight() Implements IScrollInfo.MouseWheelRight
Throw New InvalidOperationException()
End Sub
Public Sub PageLeft() Implements IScrollInfo.PageLeft
Throw New InvalidOperationException()
End Sub
Public Sub PageRight() Implements IScrollInfo.PageRight
Throw New InvalidOperationException()
End Sub
Public Sub SetHorizontalOffset(ByVal offset As Double) Implements IScrollInfo.SetHorizontalOffset
Throw New InvalidOperationException()
End Sub
Public Sub SetVerticalOffset(ByVal offset As Double) Implements IScrollInfo.SetVerticalOffset
If offset < 0 OrElse _viewport.Height >= _extent.Height Then
offset = 0
Else
If offset + _viewport.Height >= _extent.Height Then
offset = _extent.Height - _viewport.Height
End If
End If
_offset.Y = offset
If _owner IsNot Nothing Then _owner.InvalidateScrollInfo()
_trans.Y = -offset
InvalidateMeasure()
End Sub
Private _trans As TranslateTransform = New TranslateTransform()
Private _owner As ScrollViewer
Private _canHScroll As Boolean = False
Private _canVScroll As Boolean = False
Private _extent As Size = New Size(0, 0)
Private _viewport As Size = New Size(0, 0)
Private _offset As Point
End Class