Blacklight Expander problem while expanding programmatically - silverlight

I am doing a silverlight project in Silverlight 4 and I included the BlackLight project in my project so that I could use their new controls, especialy the dockpanel and the autoexpander, which is causing me at the moment some little problems.
What I would like to do is to have several auto-expander that will expand or collapsed when I click on button. In my case more specifically, each auto-expander have a set of parameter to fill, which in turn will fill the other expander and the current one would collaps and the just filled one would expand.
The idea is simple, yet when I use a button which is on one of my expander, it only works once... It would expand/collapse the first time, then after that, nothing. I trace the code and it seems to go through just fine, but the property value won't change
Here is my code
Private Sub BtnExpand_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles BtnExpand.Click
ClientExpander.IsExpanded = False
ProjetExpander.IsExpanded = True
End Sub
Could it be a known bug, or must I reset some flags to make it work?
Edit : Forgot to mention, if it makes any difference, but the IsExpanded property seems to be a dependancy property.
Thanks.

Related

A combination of winforms' controls as a prefab?

In our winforms application we often have a situation where the same panel is used in different forms. Right now I simply copy the code and the designer elements from form to form but that is obviously a terrible practice.
So I thought of making a class that could be easily added to a different form as a "component". The only problem is to be able to prototype and maintain this panel in the visual designer in such a way that if I want to change the panel's appearance in the future it gets changed for every class instance I created.
For instance I have a panel that provides search functionality:
Alongside with the code for click/textChanged events. I want to encapsulate it in a class, which I would be able to instantiate and initialize in any form's constructor to instantly add these controls (alongside events) into that form. Now it is not necessary for me to see the controls in the designer of the recepient form, however, I need to be able to see them in the designer somewhere in order to modify them if I would ever require that.
And if I do modify the appearance somehow (for instance add an extra button) these controls instantly change across the entire project, everywhere I instantiated the class.
I do know that all this can easily be done just creating a new form and encapsulating everything in it, I just wonder if it can be done for a group of controls instead.
You just described the perfect use of a User Control. It's easy to use and direct.
First Add a user COntrol to the project:
Then add the desired controls on the user control:
Build the project and you will see the UserControl on the toolbox:
Add them to the form as a standard control:
If you change the code for the user control (in this case adding a button click handler) uit will affect all the intances of that user control:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
TextBox1.Text = "Button Clicked"
End Sub
Note: If you have the Control in another project on the same solution, make sure you build that project too if you make any change.

Stopping an Unloaded event in WPF

I think this isn't the best way to go about doing this but this is the only way I can think of.
I have this WPF UserControl and it is called via a menu item (click on the menu and open the UserControl).
There are a number of things the user can do on the UserControl and I keep track of the changes made (via EF and a variable that is set to true if the user makes any changes).
Now comes the part where I know I'm doing wrongly. I want the UserControl to check if there have been changes or additions made.
I have placed this in the Unloaded event trigger.
Private Sub TheUserControl_Unloaded(sender As Object, e As RoutedEventArgs) Handles Me.Unloaded
If (changesMade) Then
Dim answer = MessageBox.Show("Changes have been.....", "Alert", MessageBoxButton.OKCancel)
If (answer = MessageBoxResult.OK) Then
If (saveChanges() = False) Then
'stop unloading???
End If
Else
MessageBox.Show("Discarding changes.")
End if
End if
End Sub
I realised that I have placed this in the wrong EventControl but I have no idea which Event Control to place it in.
So now I'm asking, where can I put this "check" to ensure that if the user navigates away from this page (by clicking on another item in the menu) they will be asked to save the changes made before the UserControl closes and if an error occurs in the saving, it would stop the UserControl from Unloading.
Thanks.

DataGridView NullReferenceException on InitializeEditingControlValue after losing focus

I have a DataGridView bound to a List[of Parts]. The last item in the list is always a 'dummy part', which is there to create an extra row in the grid so the user can start typing into the first cell to add a part to the list.
As soon as the user types more than x characters into that particular cell, a new DataGridView with search results appears under the cell where he is typing (a bit look Google's suggestions), and he can select one of the matches to add the part to the list.
I do this by handling the EditControlShowing event, which assigns the 'editing control' to a TextBox variable which has a handler for TextChanged.
The bug:
I want the focus to change to the second DataGridView (search results) if the user hits the down arrow key.
The EditControlShowing handler works fine first time, moving the focus to the second DataGridView and leaves the first DataGridView in a 'seemingly' functional state, i.e. all other event handlers work. But the second time the EditControlShowing handler fires, the DataGridView throws the NullReferenceException on InitializeEditingControlValue.
Because it is the DataGridView's own call which throw the error, the debugger brings me to "Application.Run" in my code, which isn't helpful.
However, I determined that the call which causes the DataGridView to go into that state, and the point at which exception is thrown, is when I steal focus from the first DataGridView by calling Focus() on the second DataGridView (or any other control for that matter).
If however I let the user change focus to the DataGridView (e.g. by clicking with the mouse), then the DataGridView stays fine.
Does anyone know why stealing focus away from a DataGridView during a handler for EditControlShowing should result in it behaving differently afterwards?
I've tried CancelEdit, Refresh, Enable/Disable etc...
Any suggestions on helping me find out what is going on within the DataGridView? I can't spot anything obvious by inspecting it at breakpoints before and after. I don't even know how to find out what object is null as its the DataGridView's own code...
Many thanks.
OK, I resolved this using BeginInvoke in the TextChanged event handler (code is in Boo but should make sense):
//The event handler
private def CellAsTextBoxTextChanged(sender as object, e as EventArgs):
...
self.BeginInvoke(ShowPartSelectionArea, currentCell, _CellAsTextBox.Text)
//The method which amongst other things, sets the focus to another control
private def ShowPartSelectionArea(currentCell as DataGridViewCell, searchString as string):
...
AnotherDataGridView.Focus()
...
I had previously tried using BeginInvoke directly at the point of calling Focus() on the other control, like so:
private def CellAsTextBoxTextChanged(sender as object, e as EventArgs):
...
ShowPartSelectionArea(currentCell, _CellAsTextBox.Text)
private def ShowPartSelectionArea(currentCell as DataGridViewCell, searchString as string):
...
self.BeginInvoke(AnotherDataGridView.Focus())
...
But the latter didn't work, perhaps because the first way actually allows the DataGridView's cell to finish everything it does whereas the second way doesn't.
So for anyone facing the same problem, I'd advise playing about with where in the call stack you use BeginInvoke.

Where do I find those WinForms controls?

I am looking for a WinForms control that, I believe, in the days of VB 6.0 (I can't remember if it was VB 6 or .NET 1.1) used to be called the ButtonImage or ImageButton or some such. Whatever it was called is not important.
What it used to look like and behave like is the important thing.
If you open Control Panel -> Add Remove Programs in Windows XP, the buttons on the left Change or Remove Programs, Add New Programs, etc. use tat control. I want a control that looks like that. It's a button with an image but stays pressed when it is selected.
Secondly, I am looking for a splitter. I see one in the Toolbox in Windows Forms apps, but when I try to change its size at runtime, it won't.
Do I have to use a SplitterContainer first or something?
You may make use of RadioButton control or CheckBox control.
Add the control and change the Appearance property of RadioButton to Button. Add a BackgroundImage to that.
Unfortunately this control doesn't exist in Windows Forms. You will probably find one in commercial control libraries, look for Outlook-type menus.
For the splitter, you have to use a SplitterContainer, which is two panels separated by a splitter. Then you add your controls on both splitters and will be able to move the splitter and everything.
For starters you can make the button use an image by tweaking the properties like so
Button1.Text = ""
Button1.Size = New Size(100, 100)
Button1.TextImageRelation = TextImageRelation.ImageAboveText
Button1.Image = My.Resources.Image1
That would make the button look like this
You could also swap out the image every time the user clicks with the buttons click event.
Make sure to replace image1 and image2 with the real images.
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
If Button1.Image = image1 Then
Button1.Image = image2
Else
Button1.Image = image1
End If
End Sub
You if you want the image to border and hover to be different try messing around with the button.FlatStyle = flat and the FlatAppearance property's.

Messagebox Popup to Confirm Datepicker Issue

I am using the vanilla datepicker in Silverlight 2. I bind the selected date to a value, and when that value changes I pop a messagebox to confirm that they would like to change the value.
However strange behaviour ensues when I use a messagebox straight after the datepicker's value is changed. The datepicker's popup will not close, and if you mouse over the calendar it will choose a date without having to click the mouse.
Also, after this occurs it seems to affect bindings and it cannot set the view model's property again until the page is reloaded.
This problem is rather specific so I have attached a stripped down example. Choose a date and press OK then move your mouse over the calendar to reproduce this.
My XAML -
<Grid x:Name="LayoutRoot">
<controls:DatePicker x:Name="dpTest"
Height="25"
Width="75"
SelectedDateChanged="DatePicker_SelectedDateChanged" />
</Grid>
My code behind -
Private Sub DatePicker_SelectedDateChanged(ByVal sender As System.Object, ByVal e As System.Windows.Controls.SelectionChangedEventArgs)
MessageBox.Show("Test Popup")
End Sub
Any ideas or workarounds?
Hmm this is not all that uncommon actually. A coworker of mine recently ran into very strange issues in a Windows Forms application because he was using MessageBox in response to a third party menu control's click event (before the menu had been dismissed.)
One suggestion that didn't work for him but may very well work for you is to "push" the call onto the dispatcher. That way your SelectedDateChanged handler will return before the message box actually gets shown.
Private Sub DatePicker_SelectedDateChanged( ... )
' Unfortunately my VB is rusty '
' I believe this is the correct syntax. '
Dispatcher.BeginInvoke(AddressOf ShowDateMessage)
' At this point, the message box has *not* been shown '
' It will be shown once control returns to the dispatcher '
End Sub
Private Sub ShowDateMessage()
' By this point, the DatePicker popup should be closed '
' so hopefully the issues you are seeing would be avoided '
MessageBox.Show("Test Popup")
End Sub
A couple of things to keep in mind though:
MessageBox.Show is unique in Silverlight in that it is one of the only ways to create a modal dialog. And unlike in Windows Forms where the message loop is still running, Silverlight's UI thread is stalled until it returns.
The event already takes place after the date has changed so this is not a good way to confirm the change. A cursory glance at the docs suggests there isn't a corresponding "Changing" event.
Depending on the circumstances, you might just be better off using a ChildWindow instead of MessageBox. This wouldn't have the issues you described because while it appears to be a modal dialog, it's not.
I blogged a workaround HERE that make the message box unnecessary by changing the work flow.

Resources