Thursday, February 28, 2013

Silverlight Listbox Binding Image and Tag

It took me couple days to figure this out. The requirement needs me to show the images to the listbox. I do already have the ObservableCollection of Images to set as Item Source. Only way to get specified way is through some kind of style. Here I use background of ItemContainerStyle with converter to my custom highlighting on wanted images. Xaml Code follows:

<UserControl xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"  x:Class="SkuMaintain.SKUDetailUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:localFormatter="clr-namespace:SkuMaintain.SkuDetailFormatter" >


<UserControl.Resources>
<localFormatter:SquareBackgroundConverter x:Key="SquareImageConverter"/>
</UserControl.Resources>


<ListBox x:Name="SKUImageListBox" Height="250" Width="600" SelectionMode="Single"  HorizontalContentAlignment="Left" TabIndex="1"
HorizontalAlignment="Left" VerticalAlignment="Top" Margin="3,2,115,0" >
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="Background" Value="{Binding Tag,Converter={StaticResource SquareImageConverter}}"></Setter>
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="20"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<StackPanel Orientation="Vertical">
<Image Source="{Binding Path=Source}"></Image>
</StackPanel>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>

Converter file definition (DetailFomatter.vb)


Imports System.Windows.Data
Imports System.IO

Namespace SkuDetailFormatter
    Public Class SquareBackgroundConverter
        Implements IValueConverter

        Public Function Convert(ByVal value As Object, ByVal targetType As System.Type, ByVal parameter As Object, ByVal culture As System.Globalization.CultureInfo) As Object Implements System.Windows.Data.IValueConverter.Convert
            Dim returnValue As String = String.Empty
            Dim img As New SkuOpsSvcRef.SKUImage
            Try
                If value IsNot Nothing Then
                    img = CType(value, SkuOpsSvcRef.SKUImage)
                    If Not img.IsSquare Then
                        returnValue = "Red"
                    End If
                Else
                    returnValue = String.Empty
                End If
            Catch
                returnValue = String.Empty
            End Try
            Return returnValue
        End Function

        Public Function ConvertBack(ByVal value As Object, ByVal targetType As System.Type, ByVal parameter As Object, ByVal culture As System.Globalization.CultureInfo) As Object Implements System.Windows.Data.IValueConverter.ConvertBack
            Return Nothing
        End Function
    End Class
End Namespace

Wednesday, February 20, 2013

Regular Expression - Regex for numeric


    Public Function IsNumeric(ByVal inputStr As String) As Boolean
        Dim _isNumber As Regex = New Regex("(^[+-]?\d+(,?\d*)*\.?\d*([Ee][+-]\d*)?$)|(^[\(]?[\$]?[+-]?\d?(,?\d*)*\.\d+([Ee][+-]\d*)?[\)]?$)")
        Return _isNumber.Match(inputStr).Success
    End Function



    Public Function IsPositiveNumeric(ByVal inputStr As String) As Boolean
        Dim _isNumber As Regex = New Regex("(^[+]?\d+(,?\d*)*\.?\d*([Ee][+]\d*)?$)|(^[\(]?[\$]?[+]?\d?(,?\d*)*\.\d+([Ee][+]\d*)?[\)]?$)")
        Return _isNumber.Match(inputStr).Success
    End Function



    Public Function IsNegative(ByVal inputStr As String) As Boolean
        Dim _isNegativeNumber As Regex = New Regex("^[\(]?[\$]?[-]+\d+(,?\d*)*\.?\d*([Ee][-]+\d*)?[\)]?$|^[-]+[\(]?[\$]?\d+(,?\d*)*\.?\d*([Ee][-]+\d*)?[\)]?$")
        Return _isNegativeNumber.Match(inputStr).Success
    End Function


Silverlight Auto Focus on InputBox of TabItem when TabControl changed.


    Private Sub SkuTabControl_SelectionChanged(ByVal sender As Object, ByVal e As SelectionChangedEventArgs) Handles SkuTabControl.SelectionChanged
        If SkuTabControl.SelectedItem IsNot Nothing Then
            Dim itemTab As TabItem = SkuTabControl.SelectedItem
            Dim itemGrid As Grid = itemTab.Content
            AddHandler itemGrid.Loaded, AddressOf itemGrid_Loaded
            'itemGrid.LoadedEvent()
        End If
    End Sub

    Private Sub itemGrid_Loaded(ByVal sender As Object, ByVal e As EventArgs)
        Dim itemTab As TabItem = SkuTabControl.SelectedItem
        Dim itemGrid As Grid = itemTab.Content
        Dim customInputBoxes = GetInputBoxControls(itemGrid).OfType(Of CustomTextBox.CustomTextBox)()
        Dim cTextBox As CustomTextBox.CustomTextBox
        For Each cTextBox In customInputBoxes.ToList
            If CType(cTextBox.Background, SolidColorBrush).Color = Color.FromArgb(255, 255, 255, 0) Then
                cTextBox.Focus()
                Exit For
            End If
        Next
    End Sub

    Private Function GetInputBoxControls(ByVal root As DependencyObject) As IEnumerable(Of DependencyObject)
        Try
            Dim customBoxList As New List(Of DependencyObject)()
            customBoxList.Add(root)
            For i As Integer = 0 To VisualTreeHelper.GetChildrenCount(root) - 1
                customBoxList.AddRange(GetInputBoxControls(VisualTreeHelper.GetChild(root, i)))
            Next i
            Return customBoxList
        Catch ex As Exception
            Return Nothing
        End Try
    End Function

Monday, January 14, 2013

Silverlight twoway binding helper

For real twoway binding on textbox of silverlight, you have to define a helper class and implement INotifyPropertyChanged


Partial Public Class SKUDetailUserControl
    Inherits UserControl
    Implements INotifyPropertyChanged


    ''Define multiple for two way mode
    Public Event PropertyChanged(ByVal sender As Object, ByVal e As PropertyChangedEventArgs) Implements INotifyPropertyChanged.PropertyChanged


Helper class:



    Public Class BindingHelper
        Public Shared Function GetUpdateSourceOnChange(obj As DependencyObject) As Boolean
            Return obj.GetValue(UpdateSourceOnChangeProperty)
        End Function
        Public Shared Sub SetUpdateSourceOnChange(obj As DependencyObject, value As Boolean)
            obj.SetValue(UpdateSourceOnChangeProperty, value)
        End Sub
        Public Shared ReadOnly UpdateSourceOnChangeProperty As DependencyProperty =
        DependencyProperty.RegisterAttached("UpdateSourceOnChange", GetType(Boolean), GetType(BindingHelper), New PropertyMetadata(False, AddressOf OnPropertyChanged))

        Private Shared Sub OnPropertyChanged(obj As DependencyObject, e As DependencyPropertyChangedEventArgs)
            Dim TxtBox As TextBox = obj
            If TxtBox IsNot Nothing Then
                If e.NewValue Then
                    AddHandler TxtBox.TextChanged, AddressOf OnTextChanged
                Else
                    RemoveHandler TxtBox.TextChanged, AddressOf OnTextChanged
                End If
            End If
        End Sub
        Private Shared Sub OnTextChanged(sender As Object, e As TextChangedEventArgs)
            Dim TxtBox As TextBox = sender
            If TxtBox IsNot Nothing Then
                Dim be = TxtBox.GetBindingExpression(TextBox.TextProperty)
                If be IsNot Nothing Then
                    be.UpdateSource()
                End If
            End If
        End Sub
    End Class


XAML :




Wednesday, October 3, 2012

Silverlight DataContext Changed Event (VB translate)

Silverlight DataContext Changed Event (VB.NET)


#Region "Interfaces"

Public Interface IDataContextChangedHandler(Of T As FrameworkElement)
    Sub DataContextChanged(sender As T, e As DependencyPropertyChangedEventArgs)
End Interface

Public NotInheritable Class DataContextChangedHelper(Of T As {FrameworkElement, IDataContextChangedHandler(Of T)})
    Private Const INTERNAL_CONTEXT As String = "InternalDataContext"
    Public Shared ReadOnly InternalDataContextProperty As DependencyProperty =
        DependencyProperty.Register(INTERNAL_CONTEXT, GetType([Object]), GetType(T), New PropertyMetadata(AddressOf _DataContextChanged))
    Public Shared Sub _DataContextChanged(sender As Object, e As DependencyPropertyChangedEventArgs)
        Dim control As T = DirectCast(sender, T)
        control.DataContextChanged(control, e)
    End Sub
    Public Shared Sub Bind(control As T)
        control.SetBinding(InternalDataContextProperty, New Binding)
    End Sub
End Class
#End Region




Authored originally by the Jeremy Likness

Wednesday, August 1, 2012

Great to see the workflow was taken off from the SharePoint

Used to mess up between SharePoint workflow object model and .Net framework object model. I was thinking why not separate the workflow off SharePoint. Now Microsoft made it through SharePoint 2013. Very nice!

VB.NET Function to Rotate Row Image with Bitmap in Silverlight


Couldn't find a good one to rotate images in Silverlight. The build-in RenderTransform is only for rendering on page instead of updating original. Here's the function I wrote for rotating the original images, it can be saved to bytes.

Public Function iImageRotate(ByRef bi As BitmapImage, ByVal CounterclockwiseAngle As Integer) As WriteableBitmap
        Try
            Dim wb As WriteableBitmap = New WriteableBitmap(bi)
            Dim wb_arr(,) As Integer
            ReDim Preserve wb_arr(wb.PixelWidth, wb.PixelHeight)
            For c As Integer = 0 To wb.PixelWidth
                For r As Integer = 0 To wb.PixelHeight
                    wb_arr(c, r) = wb.Pixels(wb.PixelWidth * r + c)
                Next
            Next
            Dim wb2 As WriteableBitmap
            Dim wb_arr_2(,) As Integer
            If (CounterclockwiseAngle = 0 Or CounterclockwiseAngle Mod 360 = 0) Then '0 360 plus degree
                wb2 = New WriteableBitmap(wb.PixelWidth, wb.PixelHeight)
                ReDim Preserve wb_arr_2(wb.PixelWidth, wb.PixelHeight)
                wb_arr_2 = wb_arr
            ElseIf (CounterclockwiseAngle = 90 Or CounterclockwiseAngle Mod 450 = 0) Then '90 450 plus degree
                wb2 = New WriteableBitmap(wb.PixelHeight, wb.PixelWidth)
                ReDim Preserve wb_arr_2(wb.PixelHeight, wb.PixelWidth)
                For c As Integer = 0 To (wb_arr.GetLength(0) - 1) 'width i
                    For r As Integer = 0 To (wb_arr.GetLength(1) - 1) 'height j
                        wb_arr_2(r, wb_arr.GetLength(0) - c - 1) = wb_arr(c, r) '90 Out[j, Right-i-1] = In[i, j]
                    Next
                Next
            ElseIf (CounterclockwiseAngle = 180 Or CounterclockwiseAngle Mod 540 = 0) Then '180 540 plus degree
                wb2 = New WriteableBitmap(wb.PixelWidth, wb.PixelHeight)
                ReDim Preserve wb_arr_2(wb.PixelWidth, wb.PixelHeight)
                For c As Integer = 0 To (wb_arr.GetLength(0) - 1) 'width i
                    For r As Integer = 0 To (wb_arr.GetLength(1) - 1) 'height j
                        wb_arr_2(wb_arr.GetLength(0) - c - 1, wb_arr.GetLength(1) - r - 1) = wb_arr(c, r) '180 Out[Right-i-1, Bottom-j-1] = In[i, j]
                    Next
                Next
            ElseIf (CounterclockwiseAngle = 270 Or CounterclockwiseAngle Mod 630 = 0) Then '270 630 plus degree
                wb2 = New WriteableBitmap(wb.PixelWidth, wb.PixelHeight)
                ReDim Preserve wb_arr_2(wb.PixelWidth, wb.PixelHeight)
                For c As Integer = 0 To (wb_arr.GetLength(0) - 1) 'width i
                    For r As Integer = 0 To (wb_arr.GetLength(1) - 1) 'height j
                        wb_arr_2(wb_arr.GetLength(1) - r - 1, c) = wb_arr(c, r) '270 Out[Bottom-j-1,i] = In[i, j]
                    Next
                Next
            Else
                Return Nothing
            End If

            For r As Integer = 0 To (wb_arr_2.GetLength(1) - 1)
                For c As Integer = 0 To (wb_arr_2.GetLength(0) - 1)
                    wb2.Pixels(wb2.PixelWidth * r + c) = wb_arr_2(c, r)
                Next
            Next

            Return wb2
        Catch ex As Exception
            Return Nothing
        End Try
    End Function