Cannot update a treeview inside a usercontrol - winforms

I created a usercontrol with a treeview inside it. The treeview will be populated if I add nodes in the onload handler of the usercontrol. But after that(for example, I click a button in its parent form), the treeview will not refresh. I can see the nodes was updated in memory, but it just cannot display on the screen. I called refresh/update after adding nodes. Any suggestion is appreciated.

I put a quick test together based on your description and it seems to paint just fine.
UserControl1
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Partial Class UserControl1
Inherits System.Windows.Forms.UserControl
'UserControl 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.TreeView1 = New System.Windows.Forms.TreeView
Me.SuspendLayout()
'
'TreeView1
'
Me.TreeView1.Dock = System.Windows.Forms.DockStyle.Fill
Me.TreeView1.Location = New System.Drawing.Point(0, 0)
Me.TreeView1.Name = "TreeView1"
Me.TreeView1.Size = New System.Drawing.Size(150, 150)
Me.TreeView1.TabIndex = 0
'
'UserControl1
'
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
Me.Controls.Add(Me.TreeView1)
Me.Name = "UserControl1"
Me.ResumeLayout(False)
End Sub
Friend WithEvents TreeView1 As System.Windows.Forms.TreeView
End Class
Public Class UserControl1
Public Sub AddNewNode(ByVal text As System.String)
TreeView1.Nodes.Add(text)
End Sub
End Class
Put the usercontrol on a form with a button
Public Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
UserControl11.AddNewNode(Now.ToString)
End Sub
End Class
If you are seeing proper painting as well then look at any graphics handling in the parent form then the usercontrol then the controls within the usercontrol. We really need more info.

Thank you, Dave. I figured it out. I put the usercontrol twice to my form by mistake(I cannot remember how I did it). And the one I operate is underneath the other one. That's why I cannot see it. Sorry for wasting your time.

Related

What is the best way to update the source of a XamDataGrid from a different form?

I have a XamDataGrid in my MainWindow which has a Public Shared List(Of Artikelstammdaten) as DataSource. After opening a few other forms I want to add more data to the XamDataGrid with a button click. I thought the easiest way would be just to update the DataSource, but I get an Error:
The reference to an unreleased member requires an object reference.
This is what I have tried:
Private Sub Add_Click(sender As Object, e As RoutedEventArgs)
Dim update = MainWindow.listArtikelstammdaten.Concat(CType(Import.ComparedAccessData, IEnumerable(Of Artikelstammdaten)))
dgArticleMasterData.DataSource = update
Me.Close()
End Sub
If dgArticleMasterData is defined in the MainWindow class, you need to get a reference to the MainWindow instance to be able to access it.
You should be able to find it in the Application.Current.Windows collection:
Private Sub Add_Click(sender As Object, e As RoutedEventArgs)
Dim update = MainWindow.listArtikelstammdaten.Concat(CType(Import.ComparedAccessData, IEnumerable(Of Artikelstammdaten)))
Dim window = Application.Current.Windows.OfType(Of MainWindow).FirstOrDefault()
If window IsNot Nothing Then
window.dgArticleMasterData.DataSource = update
End If
Me.Close()
End Sub

What is the correct Xaml syntax (and underlying vb code) to have a event raised by a custom Control handled in a host application view model

I have a wpf Custom Control which is now raising custom events. In a test project that I have created to test the ongoing development of the control I have placed a copy of my new custom control on the main window.
In the properties dialog for said control I can see my new event and I can type in the name for a handler for it in the code behind the main window and it's not only created for me but when I place a break point on it I see both the sender and my own event args raised in the control.
What I would now like to know Is what is the correct way to alert a viewmodel about that event respecting the principles of MVVM.
Below is the xaml markup for my custom control in the mainwindow of the test application
<WpfControls:VtlDataNavigator Name="vtlDn"
ItemsSource="{Binding Path=Orders}"
Grid.Row="1"
AddButtonVisibility="True"
CancelNewRecordButtonVisibility="True"
SaveButtonVisibility="True" />
The event I want to catch is called 'RecordControlButtonClicked' and this is the event automatically created in the mainwindow code behind
Private Sub MyCustomHandlerForControlEvent(sender As Object, e As ViewToLearn.WpfControls.VtlDataNavigatorEventArgs) Handles vtlDn.RecordControlButtonClicked
End Sub
So now what I'm after is the correct syntax in both the xaml and my new MainWindowViewModel to have this event transferred across to the viewmodel for handling (or suggestions as to the most efficient way to do this idf there is no direct route.
FYI I already have a relay command set up in the test application but the way that I've used it to bind commands in the past doesn't appear to be working with events.
Edit
One approach I've tried which appears to work is to add the following in the code behind of the main window's loaded event.
Class MainWindow
Public Sub New()
InitializeComponent
DataContext = New MainWindowViewModel
End Sub
Private Sub MainWindow_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded
Dim mvm As MainWindowViewModel = DirectCast(DataContext, MainWindowViewModel)
mvm.vtldn = vtlDn
End Sub
End Class
and then add the following in the viewmodel;
Private _vtldn As ViewToLearn.WpfControls.VtlDataNavigator
Public Property vtldn As ViewToLearn.WpfControls.VtlDataNavigator
Get
Return _vtldn
End Get
Set(ByVal Value As ViewToLearn.WpfControls.VtlDataNavigator)
If (_vtldn Is Value) Then Return
If Not IsNothing(vtldn) Then
RemoveHandler vtldn.RecordControlButtonClicked, AddressOf MyCustomHandler
End If
_vtldn = Value
If Not IsNothing(vtldn) Then
AddHandler vtldn.RecordControlButtonClicked, AddressOf MyCustomHandler
End If
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(NameOf(vtldn)))
End Set
End Property
Private Sub MyCustomHandler(ByVal sender As Object, ByVal e As VtlDataNavigatorEventArgs)
'this does get called when buttons in the custom control are clicked
End Sub
However I'm acutely aware that this is not really 'pure' mvvm so if there are better ways to do this I'm open to suggestions.

WPF TreeView Selecteditem. Issue with adding child Items (VB,net)

This may have a very simple solution but I am pretty new to this. I am trying add child items into a selected treeView item with the click of a button. Code works fine with nothing selected but seems Treeview1.selectedItem doesn't have an .Add method.
Imports System.Windows.Controls.TreeView
Class MainWindow
Private Sub addNodeButton_Click(sender As Object, e As RoutedEventArgs) Handles addNodeButton.Click
Dim n As String = "Model"
If TreeView1.SelectedItem Is Nothing Then
TreeView1.Items.Add(n)
Else
TreeView1.SelectedItem.add("test")
End If
End Sub
End Class
Any help appreciated.
Ok. I knew it would turn out to be simple. I was initially adding items as Strings insead of TreeViewItems and thus couldn't add children. Fixed code below:
Private Sub addNodeButton_Click(sender As Object, e As RoutedEventArgs) Handles addNodeButton.Click
Dim n As New TreeViewItem
n.Header = "Model"
If TreeView1.SelectedItem Is Nothing Then
TreeView1.Items.Add(n)
Else
Dim tempitem As New TreeViewItem
tempitem = TreeView1.SelectedItem
Dim newitem As New TreeViewItem
newitem.Header = "test"
tempitem.Items.Add(newitem)
End If
End Sub

My Child window not closed in WPF

I’m working in WPF and I’m facing an issue regarding NDI container
In my MainWindow Xaml I have the MainMdiContainer
<mdi:MdiContainer Theme="Aero" mdi:MdiChild.Closed="MdiChild_Closed" Margin="0,0,0,80" Name="MainMdiContainer" Grid.Row="1" Background="{x:Null}">
</mdi:MdiContainer>
Of course I have another xaml page named “Registration” and I also have a button in mainWindow to open the mdiChild
Public Sub btnAddUser_Click(sender As Object, e As System.Windows.RoutedEventArgs) Handles btnAddUser.Click
MainMdiContainer.Children.Clear()
MainMdiContainer.Children.Add(New MdiChild() With { _
.Title = "Πρόγραμμα Εσωτερικής Διαχείρισης Διορισμός Επιτροπής και Χρηστών", _
.Height = (System.Windows.SystemParameters.PrimaryScreenHeight - 500), _
.Width = (System.Windows.SystemParameters.PrimaryScreenWidth - 430), _
.Style = Nothing, _
.Content = New Registration() _
})
End Sub
Public Sub MdiChild_Closed(sender As System.Object, e As System.Windows.RoutedEventArgs)
For Each child As MdiChild In MainMdiContainer.Children.ToList()
If (child.Name.ToString().Contains("mdiChildRegistration")) Then
MainMdiContainer.Children.Remove(child)
End If
Next
End Sub
Until this stage everything goes fine and the mdiChild opens
Now I want to close the child window by pushing a button
Private Sub btnClose_Click(sender As Object, e As System.Windows.RoutedEventArgs) Handles btnClose.Click
Dim mainWin As New MainWindow
Dim mdiCont As MdiContainer = mainWin.MainMdiContainer
mainWin.MdiChild_Closed(sender, e)
End Sub
But the mdiChild it not close… in fact the Childern in mdiCont is empty.
When I add a Childern
<mdi:MdiChild IsTabStop="False" />
In MainWindow then the Childern in mdiCont is not empty it has one Child which is closed when I'm try to open my child whindow by pressing the button.
I suspect that something in the add procedure has to do with but I don’t know what.
Is there someone to assist me?
Finally I've made it to clese the child window
And all comes from the child code behind
Private Sub btnClose_Click(sender As Object, e As System.Windows.RoutedEventArgs) Handles btnClose.Click
Dim mainWin As MainWindow = Economy.Application.Current.MainWindow
mainWin.MainMdiContainer.Children.Clear()
In the declaration of mainWin it has to be refered as
'Object.Application.Current.MainWindow'
in order to transfer the child window attributes and have the ability to clear it.
Not Removed because the Remove is not clear the child window.
Thank you very much for #dymanoid.

WPF Running a command on a windows form

I have a WPF Project to which i've added a Windows Form.
The windows form has a method runme(). But I'd like to call it from the WPF form.
Currently I've used
Dim wpfForm as new wpfForm
wpfForm.Show()
to display the the WPF form from a Windows form.
I'm not sure how to send a command back though.
I've tried:
Me.parent.runme()
But this gives me errors
The only way that I can think of to do what you are wanting is to create a Custom Constructor for your Winform and pass the reference to the Wpf Window to it. There appears to be no easy way to assign a WPF Window as an Owner/Parent of a Winforms Window.
Winforms Form
Public Class Form1
Dim myParent As System.Windows.Window
Public Sub New()
InitializeComponent()
End Sub
Public Sub New(parent As System.Windows.Window)
myParent = parent
InitializeComponent()
End Sub
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
CType(myParent, MainWindow).runMe()
End Sub
End Class
Wpf Form
Class MainWindow
Dim winForm As Form1
Private Sub Button1_Click(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles Button1.Click
winForm = New Form1(Me)
winForm.Show()
End Sub
Public Sub runMe()
Me.Background = Brushes.Red
End Sub
End Class
Eventually what worked was to create an interface as suggested by Cyborgx37
Interface ILogOut
Sub DoIt()
End Interface
Class WinFormWindow : Implements ILogOut
Public Sub DoIt() Implements ILogOut.DoIt
MsgBox("Message Received!")
End Sub
End Class
You can then use the ILogOut interface to send a message to the Windows forms window from a WPF window

Resources