I am trying to get all chars of Segoe UI Symbol Font.
I got them, converted to char, converted to Hex value and added to listview as items.
So, somebody else can use their hex values for XAML projects as icon.
But the problem is this in the code:
i am always getting OverFlowException at the function Convert.ToChar.
Code is running correct, but when the index variable is bigger than 65535 which is max char value, i got overflowexception.
But if you run the code, as you will see, in the Segoe UI Symbol fontfamily there are more chars which is bigger than 65535.
Maybe my method is wrong, you can advice me another method.
MainWindow.xaml file:
<Grid Loaded="Grid_Loaded">
<ListView x:Name="listview">
<ListView.View>
<GridView>
<GridViewColumn Header="HexValue" />
</GridView>
</ListView.View>
</ListView>
</Grid>
MainWindow.xaml.vb file
Class MainWindow
Public glyph As GlyphTypeface
Dim characterMap As IDictionary(Of Integer, UShort)
Private Sub Grid_Loaded(sender As Object, e As RoutedEventArgs)
SymbolleriGetir()
End Sub
Public Sub SymbolleriGetir()
Dim segoeUiSymbol As FontFamily
For Each font As FontFamily In Fonts.SystemFontFamilies
Dim fontName As String
fontName = font.Source
If fontName = "Segoe UI Symbol" Then
segoeUiSymbol = font
End If
Next
For Each typeFace As Typeface In segoeUiSymbol.GetTypefaces
typeFace.TryGetGlyphTypeface(glyph)
If glyph IsNot Nothing Then
characterMap = glyph.CharacterToGlyphMap
Else
Continue For
End If
Next
For i As Integer = 0 To characterMap.Keys.Count
Dim index As Integer = characterMap.Keys.ElementAt(i)
Dim c As Char = Nothing
c = Convert.ToChar(index)
Dim charText As String = c.ToString()
listview.Items.Add(String.Format("&#x{0:x2};", System.Convert.ToUInt32(c)))
Next
End Sub
End Class
CharacterToGlyphMap is a lookup map
(IDictionary(Of Integer, UShort))
with the UShort being the unicode char
so it is not necessary to convert.
I am no VB developer, but I just just coded this up and tested which enumerates the chars, and creates an image glyph next to each hex value:
Wingdings:
Your loaded event handler:
(I exited after 100 due to load time)
Private Sub Grid_Loaded(ByVal sender As Object, ByVal e As RoutedEventArgs)
Dim glyph As GlyphTypeface
Dim glyphIndex As UShort
Dim typeface As System.Windows.Media.Typeface = New System.Windows.Media.Typeface("Segoe UI Symbol")
If (typeface.TryGetGlyphTypeface(glyph)) Then
Dim glyphLookupMap As IDictionary(Of Integer, UShort) = glyph.CharacterToGlyphMap
Dim x As Integer = 0
For Each kvp As KeyValuePair(Of Integer, UShort) In glyphLookupMap
Dim c As Char = Convert.ToChar(kvp.Value)
Dim glyphImage As ImageSource = Nothing
If (glyphLookupMap.TryGetValue(kvp.Key, glyphIndex)) Then
glyphImage = Me.CreateGlyph(glyph, glyphIndex, kvp.Value, Brushes.Blue)
End If
Me._listview.Items.Add(Me.CreateGlyphListboxEntry(kvp.Key, glyphImage))
Dim num As Integer = x + 1
x = num
If (num > 100) Then
Exit For
End If
Next
End If
End Sub
And here would be the Glyph image creator
Private Function CreateGlyph(ByVal glyphTypeface As System.Windows.Media.GlyphTypeface, ByVal glyphIndex As UShort, ByVal charUShortVal As UShort, ByVal foreground As Brush) As System.Windows.Media.ImageSource
Dim imageSource As System.Windows.Media.ImageSource
Dim flag As Boolean = False
Dim drawingImage As System.Windows.Media.DrawingImage = Nothing
Try
Dim glyphIndexes As IList(Of UShort) = New List(Of UShort)() From
{
charUShortVal
}
Dim advanceWidths As IList(Of Double) = New List(Of Double)() From
{
glyphTypeface.AdvanceWidths(glyphIndex)
}
Dim glyphRun As System.Windows.Media.GlyphRun = New System.Windows.Media.GlyphRun(glyphTypeface, 0, False, 1, glyphIndexes, New Point(0, 0), advanceWidths, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing)
drawingImage = New System.Windows.Media.DrawingImage(New System.Windows.Media.GlyphRunDrawing(foreground, glyphRun))
Catch exception As System.Exception
imageSource = Nothing
flag = True
End Try
If (Not flag) Then
imageSource = drawingImage
End If
flag = False
Return imageSource
End Function
And finally the Listbox Entry creator:
Private Function CreateGlyphListboxEntry(ByVal charIntValue As Integer, ByVal glyphImage As ImageSource) As FrameworkElement
Dim result As StackPanel = New StackPanel() With
{
.Orientation = Orientation.Horizontal
}
Dim text As TextBlock = New TextBlock() With
{
.Text = String.Format("{0:X}", charIntValue),
.Foreground = Brushes.Black,
.FontSize = 17,
.Margin = New Thickness(10, 0, 10, 0)
}
result.Children.Add(text)
If (glyphImage IsNot Nothing) Then
Dim image As System.Windows.Controls.Image = New System.Windows.Controls.Image()
Dim num As Double = 32
Dim num1 As Double = num
image.Height = num
image.Width = num1
image.Stretch = Stretch.Uniform
image.Source = glyphImage
result.Children.Add(image)
End If
Return result
End Function
Hope this helps!
Related
I have a ComboBox, which its ItemsSource is set to an object which inherits ObservableCollection.
The object gets refreshed with new data on a timer.
Since sometimes there is a large set of new data, I don't use the Add method on the ObservableCollection, but rather I use the following code:
For Each itm In MyNewItems
Items.Add(itm)
Next
MyBase.OnPropertyChanged(New PropertyChangedEventArgs("Count"))
OnPropertyChanged(New PropertyChangedEventArgs("Items[]"))
'NEXT LINE CAUSES ISSUE
OnCollectionChanged(New NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset))
The problem is that when the last line runs, the Text of the ComboBox gets reset to an empty string.
If I remove that line, then the issue is resolved, but the Items show old data, since the ComboBox doesn't know that new data came in
Please advise
With appreciation
UPDATE
Hi, as requested, I'm posting the relevant code here
1: The Xaml, Pretty Simple:
<Window x:Class="dlgTest"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mch="clr-namespace:Machshevet.Windows;assembly=Machshevet" >
<StackPanel>
<TextBlock Text="{Binding CaseID}"/>
<mch:TestPick Name="cmbTest" SelectedValuePath="ID" DisplayMemberPath="Name" SelectedValue="{Binding CaseID}" IsEditable="True" IsTextSearchEnabled="False" />
</StackPanel>
</Window>
2: The TestPick class, not too complex either:
Public Class TestPick
Inherits ComboBox
Dim usertyped As Boolean
Function Query() As IQueryable
Dim txt = ""
Dispatcher.Invoke(Sub() txt = Text)
Dim ret = GetSlimContext.Query("viwCase").Select("new (ID,Name,ClientName,SubjectName)")
If txt <> "" AndAlso usertyped Then ret = ret.TextFiltered(txt)
Return ret
End Function
Private Sub EntityPick_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded
Dim qs = New QuerySource(Function() Query())
Me.ItemsSource = qs
qs.Control = Me
qs.ShouldRefresh = Function() True
End Sub
Private Sub EntityPick_PreviewTextInput(sender As Object, e As TextCompositionEventArgs) Handles Me.PreviewTextInput
usertyped = True
End Sub
Private Sub TestPick_SelectionChanged(sender As Object, e As SelectionChangedEventArgs) Handles Me.SelectionChanged
If e.AddedItems.None Then
Dim a = 1
End If
End Sub
End Class
3: The QuerySource class which does all the heavy lifting
Public Class QuerySource
Inherits ObjectModel.ObservableCollection(Of Object)
Event Refreshed(sender As QuerySource, e As EventArgs)
Property RefreshSpan As TimeSpan = TimeSpan.FromSeconds(3)
Property CheckProperties As Boolean = True
Property Control As ItemsControl
Dim Timer As Threading.Timer = New Threading.Timer(Sub() TimerTick(), Nothing, 0, 600)
Dim _lastRefresh As Date?
Dim Query As Func(Of IQueryable)
Dim workingon As Date?
Sub New(Query As Func(Of IQueryable), Control As ItemsControl)
Me.Control = Control
Me.Query = Query
End Sub
Async Sub TimerTick()
Try
If Now - _lastRefresh.GetValueOrDefault < RefreshSpan Then Exit Sub
If GetLastInputTime() > 60 * 15 Then Exit Sub
Dim isvis = False
Await Control.Dispatcher.BeginInvoke(Sub() isvis = Control.IsUserVisible())
If Not isvis Then Exit Sub
If workingon.HasValue AndAlso workingon.Value > Now.AddSeconds(-15) Then Exit Sub 'if wasnt working for 15 seconds, probaly err or something
workingon = Now
Dim fq = Query.Invoke
Dim itmtype = fq.ElementType
Dim props = itmtype.CachedProperties.Where(Function(x) x.CanWrite AndAlso x.IsScalar(True)).ToList
Dim keyprops = itmtype.CachedKeyProperties.ToList
Dim newData = fq.ToObjectList
If newData Is Nothing Then Exit Sub
Dim keySelector As Func(Of Object, Object)
Dim diff As CollectionDiff(Of Object)
If itmtype.IsScalar Then 'list of strings..
keySelector = Function(x) x
Else
If keyprops.Count <> 1 Then DevError("?")
Dim kp = keyprops.FirstOrDefault
keySelector = Function(x) kp.GetValue(x)
End If
diff = CollectionDiff(Me, newData, keySelector, props, CheckProperties)
Dim toPreserve As Object
ExecIfType(Of Primitives.Selector)(Control, Sub(x) toPreserve = x.Dispatcher.Invoke(Function() x.SelectedItem))
If toPreserve IsNot Nothing Then diff.ToPreserve = {toPreserve}.ToDictionary(Function(x) x, Function(x) Nothing)
diff.PreserveOnDelete = True
If diff.ModificationCount > 400 Or diff.ClearOld Then
CheckReentrancy()
If diff.ClearOld Then
Items.Clear()
Else
For Each pair In diff.ToReplaceByIndex
Control.Dispatcher.Invoke(Sub() Items(pair.Key) = pair.Value)
Next
For Each idx In diff.GetIndexesToDelete
Items.RemoveAt(idx)
Next
End If
For Each itm In diff.ToAdd 'for mem optimization im not using addrange
Items.Add(itm)
Next
MyBase.OnPropertyChanged(New PropertyChangedEventArgs("Count"))
OnPropertyChanged(New PropertyChangedEventArgs("Items[]"))
Control.Dispatcher.Invoke(Sub() OnCollectionChanged(New NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)))
Else
Dim preservIdx = diff.ToPreserve?.Select(Function(x) Items.IndexOf(x.Key))?.ToHashSet
For Each pair In diff.ToReplaceByIndex
Control.Dispatcher.Invoke(Sub() Me(pair.Key) = pair.Value)
Next
For Each idx In diff.GetIndexesToDelete
If diff.PreserveOnDelete AndAlso preservIdx IsNot Nothing AndAlso preservIdx.Contains(idx) Then Continue For
Control.Dispatcher.Invoke(Sub() RemoveAt(idx))
Next
'don't use addrange - will cause a reset
Await Control.Dispatcher.BeginInvoke(Sub() diff.ToAdd.ForEach(Sub(x) Add(x)))
End If
_lastRefresh = Now
workingon = Nothing
Control.Dispatcher.Invoke(Sub()
Dim cvs = System.Windows.Data.CollectionViewSource.GetDefaultView(Me)
If cvs.SortDescriptions.None Then
Dim defsorts = {KVP("Name", False), KVP(NameOf(RecordBase.LastEditedOn), True), KVP(NameOf(LiteRecordBase.ID), True)}
For Each defsort In defsorts
If itmtype.HasProperty(defsort.Key) Then
cvs.SortDescriptions.Add(New SortDescription(defsort.Key, If(defsort.Value, ListSortDirection.Descending, ListSortDirection.Ascending)))
Exit For
End If
Next
End If
End Sub)
RaiseEvent Refreshed(Me, Nothing)
Catch ex As Exception
Control.Dispatcher.BeginInvoke(Sub() ex.Rethrow)
End Try
End Sub
End Class
Okay
Thanks all for chipping in, in the end it seems like my answer is actually here
ObservableCollection : calling OnCollectionChanged with multiple new items
Works like a charm, and thank you all again for your time and patience
i made a WpfControlLibrary DLL to make a custom ProgressBar to import in a WindowsForm Project. The problem is, compiling and everything works fine.
But when i try to import my dll by doing
ToolBox->Right Click->Choose Elements...->WPF Components->Browse...->Choose dll->ok
it returns this error
'...pathofthedll...' Doesn't contain any components that could be insert in your toolbox.
Here's the code of the WpfControlLibrary
<ProgressBar xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="NewProgressBar"
x:Name="ProgressBar"
Margin="20"
Value="{Binding ElementName=progress, Path=Value}" Height="30" IsIndeterminate="False" Foreground="{DynamicResource BrushRed}" Width="300">
<ProgressBar.Resources>
<SolidColorBrush x:Key="BrushRed" Color="#FFD30101"/>
<SolidColorBrush x:Key="BrushGreen" Color="#FF27D301"/>
<SolidColorBrush x:Key="BrushYellow" Color="#FFD3D301"/>
</ProgressBar.Resources>
Public Class NewProgressBar
Inherits ProgressBar
Private mColor1 As SolidColorBrush
Private mColor2 As SolidColorBrush
Private mColor3 As SolidColorBrush
Private mMaxValue As Integer = 100
Private mCurrentValue As Double = 0
Public Sub New(ByVal color1 As String, ByVal color2 As String, ByVal color3 As String)
InitializeComponent()
Dim Brush1 As New SolidColorBrush
Brush1.Color = ConvertToRbg(color1)
Me.mColor1 = Brush1
Dim Brush2 As New SolidColorBrush
Brush2.Color = ConvertToRbg(color2)
Me.mColor2 = Brush2
Dim Brush3 As New SolidColorBrush
Brush3.Color = ConvertToRbg(color3)
Me.mColor3 = Brush3
Me.Resources.Add("BrushRed", Brush1)
Me.Resources.Add("BrushYellow", Brush2)
Me.Resources.Add("BrushGreen", Brush3)
End Sub
Public Property GetColor1() As String
Get
Return mColor1.Color.ToString
End Get
Set(value As String)
Dim Brush As New SolidColorBrush
Brush.Color = ConvertToRbg(value)
Me.mColor1 = Brush
End Set
End Property
Public Property GetColor2() As String
Get
Return mColor2.Color.ToString
End Get
Set(value As String)
Dim Brush As New SolidColorBrush
Brush.Color = ConvertToRbg(value)
Me.mColor2 = Brush
End Set
End Property
Public Property GetColor3() As String
Get
Return mColor3.Color.ToString
End Get
Set(value As String)
Dim Brush As New SolidColorBrush
Brush.Color = ConvertToRbg(value)
Me.mColor3 = Brush
End Set
End Property
Public Property GetMaxValue() As Integer
Get
Return mMaxValue
End Get
Set(value As Integer)
mMaxValue = value
End Set
End Property
Private Function ConvertToRbg(ByVal HexColor As String) As Color
Dim Red As String
Dim Green As String
Dim Blue As String
HexColor = Replace(HexColor, "#", "")
Red = Val("&H" & Mid(HexColor, 1, 2))
Green = Val("&H" & Mid(HexColor, 3, 2))
Blue = Val("&H" & Mid(HexColor, 5, 2))
Return Color.FromRgb(Red, Green, Blue)
End Function
Public Sub ChangeColor()
Dim prgrss As Double = mCurrentValue / 100
Dim redbrsh As SolidColorBrush = Me.Resources("BrushRed")
Dim grnbrsh As SolidColorBrush = Me.Resources("BrushGreen")
Dim ylwbrsh As SolidColorBrush = Me.Resources("BrushYellow")
If prgrss = 1D Then
Me.Foreground = grnbrsh
ElseIf prgrss >= 0.95D And prgrss < 1D Then
Me.Foreground = ylwbrsh
Else
Me.Foreground = redbrsh
End If
Dim number As Integer = prgrss
End Sub
Public Sub ChangeValue(ByVal value As Integer)
Me.Value = (100 * value) / mMaxValue
mCurrentValue = Me.Value
End Sub
End Class
I want to be enter numbers only and does not allow non-numbers, please help me with this.
this Code in TextBox But it does not work with PasswordBox
Dim textBox As TextBox = TryCast(sender, TextBox)
Dim selectionStart As Int32 = textBox.SelectionStart
Dim selectionLength As Int32 = textBox.SelectionLength
Dim newText As [String] = [String].Empty
Dim count As Integer = 0
For Each c As [Char] In textBox.Text.ToCharArray()
If [Char].IsDigit(c) OrElse [Char].IsControl(c) Then
newText += c
End If
Next
textBox.Text = newText
textBox.SelectionStart = If(selectionStart <= textBox.Text.Length, selectionStart, textBox.Text.Length)
thank you
Private Sub PbPhone_PreviewTextInput(sender As Object, e As TextCompositionEventArgs) Handles PbPhone.PreviewTextInput
Dim regex As New Regex("[0-9]+")
If Not regex.IsMatch(e.Text) Then
e.Handled = True
End If
End Sub
The code below is throwing error:
System.Runtime.InteropServices.COMException: Exception from HRESULT:
0x80072EE4
on code line:
Dim bdDecoder As BitmapDecoder = BitmapDecoder.Create(streamPhoto, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.None)
Why? The requested URL exists and returns a 200. Google is not helping on this one.
Private Sub ResizeAndSave(ByVal imageURL As String)
Dim imgRequest As WebRequest = WebRequest.Create(imageURL)
Dim imgResponse As WebResponse = imgRequest.GetResponse()
Dim strThumbnail As String = "success.png"
Dim streamPhoto As Stream = imgResponse.GetResponseStream()
Dim memStream As New MemoryStream
streamPhoto.CopyTo(memStream)
Dim bfPhoto As BitmapFrame = ReadBitmapFrame(memStream)
Dim nThumbnailSize As Integer = 200, nWidth As Integer, nHeight As Integer
If bfPhoto.Width > bfPhoto.Height Then
nWidth = nThumbnailSize
nHeight = CInt(bfPhoto.Height * nThumbnailSize / bfPhoto.Width)
Else
nHeight = nThumbnailSize
nWidth = CInt(bfPhoto.Width * nThumbnailSize / bfPhoto.Height)
End If
Dim bfResize As BitmapFrame = FastResize(bfPhoto, nWidth, nHeight)
Dim baResize As Byte() = ToByteArray(bfResize)
Dim saveToPath As String = Server.MapPath(ConfigurationManager.AppSettings("products_photospath")) + "\49\" + strThumbnail
File.WriteAllBytes(saveToPath, baResize)
Console.WriteLine("Resize done!!!")
End Sub
Private Shared Function FastResize(bfPhoto As BitmapFrame, nWidth As Integer, nHeight As Integer) As BitmapFrame
Dim tbBitmap As New TransformedBitmap(bfPhoto, New ScaleTransform(nWidth / bfPhoto.Width, nHeight / bfPhoto.Height, 0, 0))
Return BitmapFrame.Create(tbBitmap)
End Function
Private Shared Function ToByteArray(bfResize As BitmapFrame) As Byte()
Using msStream As New MemoryStream()
Dim pbdDecoder As New PngBitmapEncoder()
pbdDecoder.Frames.Add(bfResize)
pbdDecoder.Save(msStream)
Return msStream.ToArray()
End Using
End Function
Private Shared Function ReadBitmapFrame(streamPhoto As Stream) As BitmapFrame
Dim bdDecoder As BitmapDecoder = BitmapDecoder.Create(streamPhoto, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.None)
Return bdDecoder.Frames(0)
End Function
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
ResizeAndSave("http://cdn2.emobassets.eu/media/catalog/product/1/1/1116220.jpg")
End Sub
UPDATE 1
Ok, images are now saved. But the resize only works correctly on the example .png file, and NOT on the .jpg file.
The Dell logo is saved in 200x199 px preserving transparancy, which is perfect.
The other file 1116220.jpgis saved in 625x441px...why is that not respecting the desired max width/height of 200px?
I checked into the code and the only difference I can spot is that for the png file the dimensions are a round number:
bfPhoto.Width 2000
bfPhoto.Height 1994
After FastResize executes that becomes
bfResize.Width 200
bfResize.Height 199
Where for the jpg the dimensions are
bfPhoto.Width 982,719970703125
bfPhoto.Height 695,039978027344
After FastResize executes that becomes
bfResize.Width 200
bfResize.Height 141,119995117188
So I tried to see if it was related to that image and tried with another jpg file: https://upload.wikimedia.org/wikipedia/commons/d/d8/Square-1_solved.jpg
Where for the jpg the dimensions are
bfPhoto.Width 600
bfPhoto.Height 600
After FastResize executes that becomes
bfResize.Width
bfResize.Height
That does work, so now I know it's not related to the file being a .jpg. It seems to be related to the dimensions of image 1116220.jpg, but I don't know if I can work around that by scaling differently or in some other way...
My code:
Private Sub ResizeAndSave(ByVal maxWidth As Integer, ByVal maxHeight As Integer, ByVal imageURL As String)
Dim imgRequest As WebRequest = WebRequest.Create(imageURL)
Dim imgResponse As WebResponse = imgRequest.GetResponse()
Dim streamPhoto As Stream = imgResponse.GetResponseStream()
Dim memStream As New MemoryStream
streamPhoto.CopyTo(memStream)
memStream.Position = 0
Dim bfPhoto As BitmapFrame = ReadBitmapFrame(memStream)
Dim newWidth, newHeight As Integer
Dim scaleFactor As Double
If bfPhoto.Width > maxWidth Or bfPhoto.Height > maxHeight Then
If bfPhoto.Width > maxWidth Then
scaleFactor = maxWidth / bfPhoto.Width
newWidth = Math.Round(bfPhoto.Width * scaleFactor, 0)
newHeight = Math.Round(bfPhoto.Height * scaleFactor, 0)
End If
If newHeight > maxHeight Then
scaleFactor = maxHeight / newHeight
newWidth = Math.Round(newWidth * scaleFactor, 0)
newHeight = Math.Round(newHeight * scaleFactor, 0)
End If
End If
Dim bfResize As BitmapFrame = FastResize(bfPhoto, newWidth, newHeight)
Dim baResize As Byte() = ToByteArray(bfResize)
Dim strThumbnail As String = "success" + Date.Now.Second.ToString + ".png"
Dim saveToPath As String = Server.MapPath(ConfigurationManager.AppSettings("products_photospath")) + "\49\" + strThumbnail
File.WriteAllBytes(saveToPath, baResize)
End Sub
Private Shared Function FastResize(bfPhoto As BitmapFrame, nWidth As Integer, nHeight As Integer) As BitmapFrame
Dim tbBitmap As New TransformedBitmap(bfPhoto, New ScaleTransform(nWidth / bfPhoto.Width, nHeight / bfPhoto.Height, 0, 0))
Return BitmapFrame.Create(tbBitmap)
End Function
Private Shared Function ToByteArray(bfResize As BitmapFrame) As Byte()
Using msStream As New MemoryStream()
Dim pbdDecoder As New PngBitmapEncoder()
pbdDecoder.Frames.Add(bfResize)
pbdDecoder.Save(msStream)
Return msStream.ToArray()
End Using
End Function
Private Shared Function ReadBitmapFrame(streamPhoto As Stream) As BitmapFrame
Dim bdDecoder As BitmapDecoder = BitmapDecoder.Create(streamPhoto, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.None)
Return bdDecoder.Frames(0)
End Function
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
ResizeAndSave(200, 200, "https://upload.wikimedia.org/wikipedia/commons/8/82/Dell_Logo.png")
ResizeAndSave(200, 200, "http://cdn2.emobassets.eu/media/catalog/product/1/1/1116220.jpg")
End Sub
I had a similar question for DatagridComboboxColumn but that shown me how to use the .itemsource to bind to an array outside of the datagrid. I am having a problem trying to bind to the collection that the datagrid is bound to at runtime.
I have included a working test program for how I am approaching this.
Class MainWindow
Dim ServerInfoArray As List(Of ServerInfo) = New List(Of ServerInfo)
Private Sub GetInfo(ByVal list As List(Of String))
For Each server As String In list
Dim tempip As ComboBoxItem = New ComboBoxItem
Dim tempip2 As ComboBoxItem = New ComboBoxItem
Dim sinfo As ServerInfo = New ServerInfo
tempip.Content = "192.129.123.23"
tempip2.Content = "23.213.223.21"
sinfo.IPArray.Items.Add(tempip)
sinfo.IPArray.Items.Add(tempip2)
sinfo.ServerName = server
ServerInfoArray.Add(sinfo)
DataGrid1.Items.Refresh()
Next
End Sub
Private Sub Button1_Click(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles Button1.Click
Dim serverlist As List(Of String) = New List(Of String)
serverlist.Add("Test")
serverlist.Add("Random")
serverlist.Add("Local")
GetInfo(serverlist)
End Sub
Private Sub Window_Loaded(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles MyBase.Loaded
Dim Col_Serial As DataGridTextColumn = New DataGridTextColumn()
Col_Serial.Binding = New Binding("Servername")
Col_Serial.Header = "Servername"
Col_Serial.Width = 40
Dim Col_IPArray = New DataGridComboBoxColumn()
Col_IPArray.Header = "IP Addresses"
Col_IPArray.IsReadOnly = True
'Col_IPArray.ItemsSource = serverInfoArray ' Don't know how to do this.
Col_IPArray.SelectedValuePath = "IPArray"
Col_IPArray.DisplayMemberPath = "IPArray"
DataGrid1.Columns.Add(Col_Serial)
DataGrid1.Columns.Add(Col_IPArray)
DataGrid1.ItemsSource = ServerInfoArray
End Sub
End Class
Class ServerInfo
Dim _Servername As String
Dim _IPArray As ComboBox
Public Property Servername() As String
Get
Return _Servername
End Get
Set(ByVal value As String)
_Servername = value
End Set
End Property
Public Property IPArray As ComboBox
Get
Return _IPArray
End Get
Set(ByVal value As ComboBox)
_IPArray = value
End Set
End Property
Public Sub New()
_Servername = Nothing
_IPArray = New ComboBox
End Sub
End Class
I can get all Strings and Boolean to bind.
I do not know how I can bind this DataGridComboBoxColumn to the list of attached on the property. I cannot use XAML as I need to do this at runtime.
Dim Col_Serial As DataGridComboColumn = New DataGridComboColumn()
Col_Serial.ItemSource = GetData();
Col_Serial.SelectedValuePath = "ID_value";
Col_Serial.DisplayMemberPath = "displya_col";
Col_Serial.Header = "Disk4"
Col_Serial.Width = 40
Col_Serial.IsEnabled= false;
dg.Columns.Add(Col_serial);