Get PropertyName of WPF Control - wpf

I have a ListBox that I fill with custom objects, these objects have the following properties as seen below:
Public Class VariableClass
Public Property Content As String
Public Property myNameLabel As New Label
Public Property myNameTextBox As New ComboBox
Public Property myTypeLabel As New Label
Public Property myTypeTextBox As New ComboBox
Public Overrides Function ToString() As String
Return Content.ToString()
End Function
End Class
When the user clicks on any of the custom objects, the properties of the custom objects that are WPF controls are pragmatically created in a stackpanel.
I do it like this:
If Flowchart.SelectedItem.GetType.Name = "VariableClass" Then
SetLabelProperties(Flowchart.SelectedItem.myNameLabel, "Name:", "25", LabelPanel.Width, HorizontalAlignment.Center)
SetLabelProperties(Flowchart.SelectedItem.myTypeLabel, "Type:", "25", LabelPanel.Width, HorizontalAlignment.Center)
SetComboBoxProperties(Flowchart.SelectedItem.myNameTextBox, Flowchart.SelectedItem.myNameTextBox.Text, "25", ValuePanel.Width, VerticalContentAlignment.Center, True, True)
SetComboBoxProperties(Flowchart.SelectedItem.myTypeTextBox, Flowchart.SelectedItem.myTypeTextBox.Text, "25", ValuePanel.Width, VerticalContentAlignment.Center, True, True)
AddPropertiesInStackPanel(Flowchart.SelectedItem)
End if
The functions:
Function SetLabelProperties(myLabel As Label, myName As String, myHeight As String, myWidth As String, myHorizontalAlignment As HorizontalAlignment)
myLabel.Content = myName
myLabel.Height = myHeight
myLabel.Width = myWidth
myLabel.HorizontalContentAlignment = myHorizontalAlignment
End Function
Function SetComboBoxProperties(myComboBox As ComboBox, myName As String, myHeight As String, myWidth As String, myVerticalAlignment As VerticalAlignment, Editable As Boolean, SearchEnabled As Boolean)
myComboBox.IsEditable = Editable
myComboBox.IsTextSearchEnabled = SearchEnabled
myComboBox.Text = myName
myComboBox.Height = myHeight
myComboBox.Width = myWidth
myComboBox.VerticalContentAlignment = myVerticalAlignment
Dim myDouble As Double = 0
Dim myStatic As ResourceKey = SystemParameters.VerticalScrollBarWidthKey
myComboBox.Resources.Add(myStatic, myDouble)
End Function
Function SetTextBoxProperties(myTextBox As TextBox, myName As String, myHeight As String, myWidth As String, myVerticalAlignment As VerticalAlignment)
myTextBox.Text = myName
myTextBox.Height = myHeight
myTextBox.Width = myWidth
myTextBox.VerticalContentAlignment = myVerticalAlignment
End Function
Function AddPropertiesInStackPanel(myObject As Object)
Dim info() As PropertyInfo = myObject.GetType().GetProperties()
For Each item In info
Dim myElementSplit = Split(item.PropertyType.FullName, ".")(UBound(Split(item.PropertyType.FullName, ".")))
If myElementSplit = "Label" Then
LabelPanel.Children.Add(item.GetValue(myObject))
LabelPanel.Children.Add(New Separator With {.Height = 1, .Opacity = 0})
ElseIf myElementSplit = "ComboBox" Then
ValuePanel.Children.Add(item.GetValue(myObject))
ValuePanel.Children.Add(New Separator With {.Height = 1, .Opacity = 0})
ElseIf myElementSplit = "TextBox" Then
ValuePanel.Children.Add(item.GetValue(myObject))
ValuePanel.Children.Add(New Separator With {.Height = 1, .Opacity = 0})
End If
Next
End Function
I have tried this event that triggers whenever the user types into a ComboBox in the stackpanel.
Private Sub ValuePanel_PreviewKeyDown(sender As Object, e As KeyEventArgs) Handles ValuePanel.PreviewKeyDown
Dim myElement = e.OriginalSource
Dim myVar = GetValue(myElement).GetType().GetProperty("PropertyName")
End Sub
But myElement is not a DependencyProperty and it cannot be cast to one.

The control that raises the PreviewKeyDown doesn't know which propery of your custom object it "came" from. You can however store this information in the Tag property of the control, e.g.:
myNameTextBox.Tag = "myNameLabel"
...and then retrieve it in the event handler using this property:
Private Sub ValuePanel_PreviewKeyDown(sender As Object, e As KeyEventArgs)
Dim myElement = CType(e.OriginalSource, FrameworkElement)
Dim propertyName = myElement.Tag.ToString()
End Sub

Related

How to get selected value on SelectionChanged event of ComboBox in ViewModel (WPF-MVVM)?

I am new in WPF Application with pattern MVVM and I have a particular situation that I do not know how to solve it.
I builted a system to switch environments (Productive, WorkDebug and HomeDebug) with changing only a parameter. I created this system, because every environment have different type Classes and without it, every time that I need to switch environment I have to perform commenct/uncomment on properties and so on.
I have a Class with a switch that handles the execution and determine what type of variable initialize:
Private _modalitaEsecuzione As Byte
'DATABASE
Private _ambienteDatabase As AmbienteDatabase
Private _databaseProduttivo As DatabaseProduttivoLinqToSqlDataContext
Private _databaseDebug As DatabaseLinqToSqlDataContext
Private _databaseDebugHome As DatabaseLinqToSqlHomeDataContext
Private _ambienteSettori As AmbienteSettore
Private _ambienteUtente As AmbienteUtente
Private _ambienteProprietaSettore As AmbienteProprietaSettore
Public Sub New(produttivoDebug As Byte)
_modalitaEsecuzione = produttivoDebug
End Sub
Public Function ImpostaVariabile(tipoFunzione As String)
Select Case tipoFunzione
Case "percorsoFilesFilRouge"
If _modalitaEsecuzione = AmbienteEsecuzioneEnum.Produttivo Then
Return "productivePath"
ElseIf _modalitaEsecuzione = AmbienteEsecuzioneEnum.DebugLavoro Then
Return "workDebugPath"
Else
Return "homeDebugPath"
End If
Case "databaseConnection"
If _modalitaEsecuzione = AmbienteEsecuzioneEnum.Produttivo Then
_ambienteDatabase = New AmbienteDatabase() With {
.DatabaseProduttivo = New DatabaseProduttivoLinqToSqlDataContext(ConfigurationManager.
ConnectionStrings("productiveConnection").ToString())
}
Return _ambienteDatabase
ElseIf _modalitaEsecuzione = AmbienteEsecuzioneEnum.DebugLavoro Then
_ambienteDatabase = New AmbienteDatabase() With {
.DatabaseDebugLavoro = New DatabaseLinqToSqlDataContext(MySettings.Default.DebugConnection)
}
Return _ambienteDatabase
Else
_ambienteDatabase = New AmbienteDatabase() With {
.DatabaseDebugHome = New DatabaseLinqToSqlHomeDataContext(ConfigurationManager.
ConnectionStrings("HomeDebugConnection").ToString())
}
Return _ambienteDatabase
End If
Case "listaSettori"
If _modalitaEsecuzione = AmbienteEsecuzioneEnum.Produttivo Then
_ambienteSettori = New AmbienteSettore() With {
.SettoriProduttivo = New ObservableCollection(Of T_Settore)(_ambienteDatabase.DatabaseProduttivo.
T_Settore.Where(Function(s) s.NSET_Disponibilita > 0).
OrderBy(Function(s) s.TSET_Descrizione).ToList())
}
Return _ambienteSettori
ElseIf _modalitaEsecuzione = AmbienteEsecuzioneEnum.DebugLavoro Then
_ambienteSettori = New AmbienteSettore() With {
.SettoriDebugLavoro = New ObservableCollection(Of T_Settore_Debug)(_ambienteDatabase.
DatabaseDebugLavoro.
T_Settore_Debug.Where(Function(s) s.NSET_Disponibilita > 0).
OrderBy(Function(s) s.TSET_Descrizione).ToList())
}
Return _ambienteSettori
Else
_ambienteSettori = New AmbienteSettore() With {
.SettoriDebugHome = New ObservableCollection(Of T_Settore_Debug_Home)(_ambienteDatabase.
DatabaseDebugHome.
T_Settore_Debug_Homes.Where(Function(s) s.NSET_Disponibilita > 0).
OrderBy(Function(s) s.TSET_Descrizione).ToList())
}
Return _ambienteSettori
End If
Case "listaUtenti"
If _modalitaEsecuzione = AmbienteEsecuzioneEnum.Produttivo Then
_ambienteUtente = New AmbienteUtente() With {
.UtentiDatabaseProduttivo = _ambienteDatabase.DatabaseProduttivo.T_Ospite.ToList()
}
Return _ambienteUtente
ElseIf _modalitaEsecuzione = AmbienteEsecuzioneEnum.DebugLavoro Then
_ambienteUtente = New AmbienteUtente() With {
.UtentiDatabaseDebug = _ambienteDatabase.DatabaseDebugLavoro.Utente_Debug.ToList()
}
Return _ambienteUtente
Else
_ambienteUtente = New AmbienteUtente() With {
.UtentiDatabaseDebugHome = _ambienteDatabase.DatabaseDebugHome.Utente_Debug_Homes.ToList()
}
Return _ambienteUtente
End If
Case "proprietaSettore"
If _modalitaEsecuzione = AmbienteEsecuzioneEnum.Produttivo Then
Dim proprietaSettoreProduttivo = _ambienteDatabase.DatabaseProduttivo.T_Settore.
Where(Function(s) s.TSET_Codice Is "SND").
SingleOrDefault()
_ambienteProprietaSettore = New AmbienteProprietaSettore() With {
.SettoreProduttivo = proprietaSettoreProduttivo,
.CodiceSettore = proprietaSettoreProduttivo.TSET_Codice
}
Return _ambienteProprietaSettore
ElseIf _modalitaEsecuzione = AmbienteEsecuzioneEnum.DebugLavoro Then
Dim proprietaSettoreDebug = _ambienteDatabase.DatabaseDebugLavoro.T_Settore_Debug.
Where(Function(s) s.TSET_Codice Is "INF").
SingleOrDefault()
_ambienteProprietaSettore = New AmbienteProprietaSettore() With {
.SettoreDebug = proprietaSettoreDebug,
.CodiceSettore = proprietaSettoreDebug.TSET_Codice
}
Return _ambienteProprietaSettore
Else
Dim proprietaSettoreDebugHome = _ambienteDatabase.DatabaseDebugHome.T_Settore_Debug_Homes.
Where(Function(s) s.TSET_Codice Is "INF").
SingleOrDefault()
_ambienteProprietaSettore = New AmbienteProprietaSettore() With {
.SettoreDebug = proprietaSettoreDebugHome,
.CodiceSettore = proprietaSettoreDebugHome.TSET_Codice
}
Return _ambienteProprietaSettore
End If
Case "utente"
End Select
Return ""
End Function
End Class
In my ViewModel I instantiate this class and I set various properties with that object. Now, I have a list of object that is bound to the View and the type of this list depends on the environments that is selected. In this class I have three different type classes properties who corresponds to a specific environment:
Public Class AmbienteSettore
Private _settoriProduttivo As ObservableCollection(Of T_Settore)
Public Property SettoriProduttivo() As ObservableCollection(Of T_Settore)
Get
Return _settoriProduttivo
End Get
Set(ByVal value As ObservableCollection(Of T_Settore))
_settoriProduttivo = value
End Set
End Property
Private _settoriDebugLavoro As ObservableCollection(Of T_Settore_Debug)
Public Property SettoriDebugLavoro() As ObservableCollection(Of T_Settore_Debug)
Get
Return _settoriDebugLavoro
End Get
Set(ByVal value As ObservableCollection(Of T_Settore_Debug))
_settoriDebugLavoro = value
End Set
End Property
Private _settoriDebugHome As ObservableCollection(Of T_Settore_Debug_Home)
Public Property SettoriDebugHome() As ObservableCollection(Of T_Settore_Debug_Home)
Get
Return _settoriDebugHome
End Get
Set(ByVal value As ObservableCollection(Of T_Settore_Debug_Home))
_settoriDebugHome = value
End Set
End Property
Public Function GetSettori()
Return SettoriProduttivo
End Function
End Class
In my ViewModel I declare a property of this class to determine what kind of list. This properties is bound with the combobox and I use a Converter to determine the list type and then to pass it to the XAML that it will be able to manage the list properly.
The Converter convert the object to their right list (Productive, WorkDebug and HomeDebug):
Public Class ListaSettoriConverter
Implements IValueConverter
Public Function Convert(value As Object, targetType As Type, parameter As Object, culture As CultureInfo) As Object Implements IValueConverter.Convert
value = DirectCast(value, AmbienteSettore)
If value.SettoriProduttivo IsNot Nothing Then
Return value.SettoriProduttivo
ElseIf value.SettoriDebugLavoro IsNot Nothing Then
Return value.SettoriDebugLavoro
Else
Return value.SettoriDebugHome
End If
End Function
Public Function ConvertBack(value As Object, targetType As Type, parameter As Object, culture As CultureInfo) As Object Implements IValueConverter.ConvertBack
Throw New NotImplementedException()
End Function
End Class
To intercept the SelectionChanged I need to link a single object of the list with a single property in my ViewModel. This property has the same logic of the list: I have different type classes based on environment.
The class of the single property is
Public Class AmbienteProprietaSettore
Private _settoreProduttivo As T_Settore
Public Property SettoreProduttivo() As T_Settore
Get
Return _settoreProduttivo
End Get
Set(ByVal value As T_Settore)
_settoreProduttivo = value
End Set
End Property
Private _settoreDebug As T_Settore_Debug
Public Property SettoreDebug() As T_Settore_Debug
Get
Return _settoreDebug
End Get
Set(ByVal value As T_Settore_Debug)
_settoreDebug = value
End Set
End Property
Private _settoreDebugHome As T_Settore_Debug_Home
Public Property SettoreDebugHome() As T_Settore_Debug_Home
Get
Return _settoreDebugHome
End Get
Set(ByVal value As T_Settore_Debug_Home)
_settoreDebugHome = value
End Set
End Property
End Class
This is the XAML ComboBox:
<ComboBox HorizontalAlignment="Left" VerticalAlignment="Center" Width="200" Margin="5 0 0 0"
ItemsSource="{Binding Path=AmbienteSettore, Converter={StaticResource ListaSettoriConverter}}"
SelectedItem="{Binding Path=AmbienteProprietaSettore, UpdateSourceTrigger=PropertyChanged,
Converter={StaticResource SettoreConverter}}"
The question is, how can I manage the NotifyPropertyChanged of a property that is inside a property of the ViewModel? Because the binding is based on the class which has the right properties set inside it.
I hope that is clear and thanks in advance

Long ComboBox Text, Can't be Displayed Fully

As the image shown, the combo box text in my case is very long.
Without changing the width of the combo box, is there any method to show full text when the user hovers on it?
Without changing the width of the combo box, is there any method to show full text when the user hovers on it?
You can use the ToolTip component to show the items with long text when the mouse pointer hovers over the control. Whenever the SelectedIndex changes, measure the selected item by the TextRenderer.MeasureText method, and if the string's width is greater than the editbox's, set the long string as a tooltip for the control.
Note: The width of the EditBox = ComboBox.Width - ButtonWidth. You can get the ButtonWidth from the SystemInformation.VerticalScrollBarWidth property.
To apply this feature, let's create a little class and inherit the ComboBox control.
C#
// +
// using System.ComponentModel;
[DesignerCategory("Code")]
public class ComboBoxEx : ComboBox
{
private readonly ToolTip ttp;
public ComboBoxEx() : base() => ttp = new ToolTip();
private bool _showItemToolTip = true;
[DefaultValue(true)]
public bool ShowItemToolTip
{
get => _showItemToolTip;
set
{
if (_showItemToolTip != value)
{
_showItemToolTip = value;
ttp.SetToolTip(this, string.Empty);
}
}
}
protected override void OnSelectedIndexChanged(EventArgs e)
{
base.OnSelectedIndexChanged(e);
if (ShowItemToolTip)
{
string str = string.Empty;
if (SelectedIndex >= 0)
{
var sz = TextRenderer.MeasureText(Text, Font);
if (sz.Width > Width - SystemInformation.VerticalScrollBarWidth)
str = Text;
}
ttp.SetToolTip(this, str);
}
}
protected override void Dispose(bool disposing)
{
if (disposing) ttp.Dispose();
base.Dispose(disposing);
}
}
VB.Net
' +
' Imports System.ComponentModel
<DesignerCategory("Code")>
Public Class ComboBoxEx
Inherits ComboBox
Private ReadOnly ttp As ToolTip
Sub New()
MyBase.New
ttp = New ToolTip()
End Sub
Private _showItemToolTip As Boolean = True
<DefaultValue(True)>
Public Property ShowItemToolTip As Boolean
Get
Return _showItemToolTip
End Get
Set(value As Boolean)
If (_showItemToolTip <> value) Then
_showItemToolTip = value
ttp.SetToolTip(Me, String.Empty)
End If
End Set
End Property
Protected Overrides Sub OnSelectedIndexChanged(e As EventArgs)
MyBase.OnSelectedIndexChanged(e)
If ShowItemToolTip Then
Dim str = ""
If SelectedIndex >= 0 Then
Dim sz = TextRenderer.MeasureText(Text, Font)
If sz.Width > Width - SystemInformation.VerticalScrollBarWidth Then
str = Text
End If
End If
ttp.SetToolTip(Me, str)
End If
End Sub
Protected Overrides Sub Dispose(disposing As Boolean)
If disposing Then ttp.Dispose()
MyBase.Dispose(disposing)
End Sub
End Class
You can use the same approach if you don't want to subclass. Drop a ToolTip component and handle the ComboBox.SelectedIndexChanged event as shown above.

Top ListView in SplitContainer won't add vertical scrollbar

I have a Winforms app with two ListViews in a SplitContainer.
When I drag the splitter to hide part of the Panel2 ListView items, it automatically adds a vertical scrollbar.
When I drag the splitter to hide part of the Panel1 ListView items, it does not add a vertical scrollbar.
Changing which ListView is in which Panel has the same behavior. It's as if something about the SplitContainer or its panels is controlling whether the vertical scrollbar is added to the ListView in Panel1 or not. How to make whichever ListView is in the top Panel1 also automatically add the vertical scrollbar?
To replicate, create a simple Winforms application with one form. Here is my form code followed by the designer form code.
Public Class Form1
Private Sub Form1_Shown(sender As Object, e As EventArgs) Handles Me.Shown
Timer1.Enabled = True
End Sub
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
Try
Timer1.Enabled = False
TechDateList.BeginUpdate()
TechDateList.Items.Clear()
StopsList.BeginUpdate()
StopsList.Items.Clear()
For i As Integer = 1 To 5
Dim techItem = New ListViewItem
techItem.UseItemStyleForSubItems = False
techItem.SubItems(0).Text = Date.Now.ToString("MMM dd, yyyy")
techItem.SubItems.Add(String.Format("Tech {0}", i))
TechDateList.Items.Add(techItem)
Next
For i As Integer = 1 To 5
Dim stopItem = New ListViewItem
stopItem.UseItemStyleForSubItems = False
stopItem.SubItems(0).Text = Choose(i, "AAA", "BBB", "CCC", "DDD", "EEE")
stopItem.SubItems.Add(String.Format("Stop {0}", i))
StopsList.Items.Add(stopItem)
Next
Catch ex As Exception
MsgBox(ex.ToString(), MsgBoxStyle.Critical + MsgBoxStyle.OkOnly, "Timer1_Tick Error 1")
Finally
TechDateList.EndUpdate()
StopsList.EndUpdate()
End Try
Try
ListSplitter.Panel1Collapsed = False
ListSplitter.SplitterDistance = 125
ListSplitter.SplitterWidth = 6
TechDateList.Items.Item(0).Selected = True
Catch ex As Exception
MsgBox(ex.ToString(), MsgBoxStyle.Critical + MsgBoxStyle.OkOnly, "Timer1_Tick Error 2")
End Try
End Sub
End Class
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Partial Class Form1
Inherits System.Windows.Forms.Form
'Form overrides dispose to clean up the component list.
<System.Diagnostics.DebuggerNonUserCode()> _
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
Try
If disposing AndAlso components IsNot Nothing Then
components.Dispose()
End If
Finally
MyBase.Dispose(disposing)
End Try
End Sub
'Required by the Windows Form Designer
Private components As System.ComponentModel.IContainer
'NOTE: The following procedure is required by the Windows Form Designer
'It can be modified using the Windows Form Designer.
'Do not modify it using the code editor.
<System.Diagnostics.DebuggerStepThrough()> _
Private Sub InitializeComponent()
Me.components = New System.ComponentModel.Container()
Me.ListSplitter = New System.Windows.Forms.SplitContainer()
Me.TechDateList = New System.Windows.Forms.ListView()
Me.UInitial = CType(New System.Windows.Forms.ColumnHeader(), System.Windows.Forms.ColumnHeader)
Me.SchedDate = CType(New System.Windows.Forms.ColumnHeader(), System.Windows.Forms.ColumnHeader)
Me.StopsList = New System.Windows.Forms.ListView()
Me.StopNum = CType(New System.Windows.Forms.ColumnHeader(), System.Windows.Forms.ColumnHeader)
Me.StopName = CType(New System.Windows.Forms.ColumnHeader(), System.Windows.Forms.ColumnHeader)
Me.Timer1 = New System.Windows.Forms.Timer(Me.components)
CType(Me.ListSplitter, System.ComponentModel.ISupportInitialize).BeginInit()
Me.ListSplitter.Panel1.SuspendLayout()
Me.ListSplitter.Panel2.SuspendLayout()
Me.ListSplitter.SuspendLayout()
Me.SuspendLayout()
'
'ListSplitter
'
Me.ListSplitter.Dock = System.Windows.Forms.DockStyle.Fill
Me.ListSplitter.FixedPanel = System.Windows.Forms.FixedPanel.Panel1
Me.ListSplitter.Location = New System.Drawing.Point(0, 0)
Me.ListSplitter.Name = "ListSplitter"
Me.ListSplitter.Orientation = System.Windows.Forms.Orientation.Horizontal
'
'ListSplitter.Panel1
'
Me.ListSplitter.Panel1.Controls.Add(Me.TechDateList)
Me.ListSplitter.Panel1Collapsed = True
Me.ListSplitter.Panel1MinSize = 0
'
'ListSplitter.Panel2
'
Me.ListSplitter.Panel2.Controls.Add(Me.StopsList)
Me.ListSplitter.Size = New System.Drawing.Size(384, 261)
Me.ListSplitter.SplitterDistance = 25
Me.ListSplitter.SplitterWidth = 1
Me.ListSplitter.TabIndex = 1
'
'TechDateList
'
Me.TechDateList.Anchor = CType(((System.Windows.Forms.AnchorStyles.Top Or System.Windows.Forms.AnchorStyles.Bottom) _
Or System.Windows.Forms.AnchorStyles.Left), System.Windows.Forms.AnchorStyles)
Me.TechDateList.Columns.AddRange(New System.Windows.Forms.ColumnHeader() {Me.UInitial, Me.SchedDate})
Me.TechDateList.FullRowSelect = True
Me.TechDateList.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.None
Me.TechDateList.HideSelection = False
Me.TechDateList.LabelWrap = False
Me.TechDateList.Location = New System.Drawing.Point(4, 0)
Me.TechDateList.Margin = New System.Windows.Forms.Padding(0)
Me.TechDateList.MultiSelect = False
Me.TechDateList.Name = "TechDateList"
Me.TechDateList.ShowGroups = False
Me.TechDateList.Size = New System.Drawing.Size(258, 166)
Me.TechDateList.TabIndex = 0
Me.TechDateList.UseCompatibleStateImageBehavior = False
Me.TechDateList.View = System.Windows.Forms.View.Details
'
'UInitial
'
Me.UInitial.Text = "Route"
Me.UInitial.TextAlign = System.Windows.Forms.HorizontalAlignment.Center
Me.UInitial.Width = 100
'
'SchedDate
'
Me.SchedDate.Text = "Job Date"
Me.SchedDate.Width = 133
'
'StopsList
'
Me.StopsList.Anchor = CType(((System.Windows.Forms.AnchorStyles.Top Or System.Windows.Forms.AnchorStyles.Bottom) _
Or System.Windows.Forms.AnchorStyles.Left), System.Windows.Forms.AnchorStyles)
Me.StopsList.Columns.AddRange(New System.Windows.Forms.ColumnHeader() {Me.StopNum, Me.StopName})
Me.StopsList.FullRowSelect = True
Me.StopsList.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.None
Me.StopsList.HideSelection = False
Me.StopsList.LabelWrap = False
Me.StopsList.Location = New System.Drawing.Point(4, 0)
Me.StopsList.Margin = New System.Windows.Forms.Padding(0)
Me.StopsList.MultiSelect = False
Me.StopsList.Name = "StopsList"
Me.StopsList.ShowGroups = False
Me.StopsList.Size = New System.Drawing.Size(258, 252)
Me.StopsList.TabIndex = 0
Me.StopsList.UseCompatibleStateImageBehavior = False
Me.StopsList.View = System.Windows.Forms.View.Details
'
'StopNum
'
Me.StopNum.Text = "000"
Me.StopNum.TextAlign = System.Windows.Forms.HorizontalAlignment.Center
Me.StopNum.Width = 34
'
'StopName
'
Me.StopName.Text = "Stop Name"
Me.StopName.Width = 199
'
'Timer1
'
Me.Timer1.Interval = 250
'
'Form1
'
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
Me.ClientSize = New System.Drawing.Size(384, 261)
Me.Controls.Add(Me.ListSplitter)
Me.Name = "Form1"
Me.Text = "Form1"
Me.ListSplitter.Panel1.ResumeLayout(False)
Me.ListSplitter.Panel2.ResumeLayout(False)
CType(Me.ListSplitter, System.ComponentModel.ISupportInitialize).EndInit()
Me.ListSplitter.ResumeLayout(False)
Me.ResumeLayout(False)
End Sub
Friend WithEvents ListSplitter As SplitContainer
Friend WithEvents TechDateList As ListView
Friend WithEvents UInitial As ColumnHeader
Friend WithEvents SchedDate As ColumnHeader
Friend WithEvents StopsList As ListView
Friend WithEvents StopNum As ColumnHeader
Friend WithEvents StopName As ColumnHeader
Friend WithEvents Timer1 As Timer
End Class
From what I see in Designer code, TechDateList Height exceeds ListSplitter.Panel1 Height:
Me.ListSplitter.SplitterDistance = 25
Me.TechDateList.Size = New System.Drawing.Size(258, 166)
make sure that TechDateList fits Panel1 in Designer, e.g
Me.ListSplitter.SplitterDistance = 125
Me.TechDateList.Size = New System.Drawing.Size(258, 120)
and then resize will work as expected.
consider also docking TechDateList to Left - the list will get maximum possible Height and will resize with Panel1
I'm guessing that moving the splitter is resizing the ListView in Panel2 but not resizing the ListView in Panel1. I'm probably missing something simple somewhere. Regardless, if I add this code to the form, I get the desired results:
Private Sub ListSplitter_SplitterMoved(sender As Object, e As SplitterEventArgs) Handles ListSplitter.SplitterMoved
TechDateList.Height = ListSplitter.Panel1.Height
End Sub

ToolTip stays open

I need to show ToolTip on a certain control for a certain period of time, with this code I get the ToolTip to show, but it won't disappear:
Public Sub tooltipControl(ByVal kontrola As Object, ByVal opened As Boolean, ByVal Optional poruka As String = "", ByVal Optional boja As Object = Nothing)
Dim ellipse1 As New Ellipse
ellipse1.Height = 25
ellipse1.Width = 50
ellipse1.Fill = Brushes.Gray
ellipse1.HorizontalAlignment = HorizontalAlignment.Left
Dim bubble As New ToolTip
bubble.PlacementTarget = kontrola
bubble.Placement = PlacementMode.Bottom
ToolTipService.SetShowDuration(kontrola, 5000)
Dim bdec As New BulletDecorator
Dim littleEllipse As New Ellipse
littleEllipse.Height = 20
littleEllipse.Width = 20
littleEllipse.Fill = boja
bdec.Bullet = littleEllipse
Dim tipText As New TextBlock
tipText.Text = poruka
bdec.Child = tipText
bubble.Content = bdec
bubble.IsOpen = True
kontrola.ToolTip = bubble
End Sub
Set the duration on the elemtent the tooltip belongs to
ToolTipService.SetShowDuration(kontrola, 5000)
and add the tooltip before opening it
kontrola.ToolTip = bubble
bubble.IsOpen = True

WPF - Remove mnemonic function from textbox

Just discovered what is causing a HTML editor to throw the toys out when using a certain letter on a keyboard...
On the same page there are textboxes that contain things like html page name, title, navigate URL, menu text.... If one of the textboxes contains text with an underscore (say 'Test_Page') then the letter 'P' will not function in the HTML editor. I'm guessing (and could be way off base here as I didn't think textbox.txt could do this unlike Label.content) that WPF is taking the text entry and using it as a mnemonic key.. I do know that setting RecognisesAccessKey to false might cure it, but can't find a way to add that property or access ContentPresenter...
This is the class that I use to create the control and ideally would like to set it here
Public Class TBx
Inherits TextBox
Public Shared IsNewRecordProperty As DependencyProperty = DependencyProperty.Register("IsNewRecord", GetType(Boolean), GetType(TBx), New PropertyMetadata(New PropertyChangedCallback(AddressOf IsNewRecordChanged)))
Public Property IsNewRecord As Boolean
Get
Return GetValue(IsNewRecordProperty)
End Get
Set(value As Boolean)
SetValue(IsNewRecordProperty, value)
End Set
End Property
Protected Overrides Sub OnInitialized(e As System.EventArgs)
MyBase.OnInitialized(e)
VerticalAlignment = Windows.VerticalAlignment.Center
HorizontalAlignment = Windows.HorizontalAlignment.Left
BorderBrush = New SolidColorBrush(Colors.Silver)
Height = 22
SpellCheck.IsEnabled = True
UndoLimit = 0
If IsNewRecord = True Then
BorderThickness = New Thickness(1)
IsReadOnly = False
Background = New SolidColorBrush(Colors.White)
Else
BorderThickness = New Thickness(0)
IsReadOnly = True
Background = New SolidColorBrush(Colors.Transparent)
End If
End Sub
Private Shared Sub IsNewRecordChanged(sender As DependencyObject, e As DependencyPropertyChangedEventArgs)
Dim vControl As TBx = TryCast(sender, TBx)
Dim vBoolean As Boolean = e.NewValue
If vBoolean = True Then
vControl.BorderThickness = New Thickness(1)
vControl.IsReadOnly = False
vControl.Background = New SolidColorBrush(Colors.White)
Else
vControl.BorderThickness = New Thickness(0)
vControl.IsReadOnly = True
vControl.Background = New SolidColorBrush(Colors.Transparent)
End If
End Sub
End Class
Thank you
Couldn't find an easy way to do this from the class, but this works on the page
Dim CP As New ContentPresenter
CP.RecognizesAccessKey = False
Then add the TextBox to the ContentPresenter
Case 1
vLabel.Text = "Page Name"
With vTB
.Width = 200
.Name = vName & "PageNameTB"
.ToolTip = "This is the short name for the page"
.IsNewRecord = IsNewRecord
End With
CP.Content = vTB
The add the CP to the grid
RegisterControl(SecurePage_Grid, vTB)
Grid.SetColumn(vLabel, 0)
Grid.SetRow(vLabel, i)
If i = 1 Then
Grid.SetRow(CP, i)
Grid.SetColumn(CP, 1)
Else
Grid.SetRow(vTB, i)
Grid.SetColumn(vTB, 1)
End If
vGrid.Children.Add(vLabel)
If i = 1 Then
vGrid.Children.Add(CP)
Else
vGrid.Children.Add(vTB)
End If

Resources