Binding Custom object to Checkbox in VB.NET - vb.net

I am trying to bind a checkbox to a custom object boolean property as follows:
chkTableIsReadonly.DataBindings.Add(New Binding("Checked", objectBindingSource, "ApplyforVisa", True, DataSourceUpdateMode.OnPropertyChanged, False))
The custom class supports the INotifyPropertyChanged interface.
Everything works find when I initially bind the checkbox to a new object:
objectBindingSource.Datasource = new objectToBindTo
Here is the odd part:
If I check the box, the property Set gets called and the INotifyPropertyChanged event gets called and everyone is happy.
If I uncheck the same box, the property Set doesn't get called, the INotifyPropertyChanged event never gets called and (the worse part), I cannot navigate to another record.
I have tried capturing the CheckedChanged event to set the object.ApplyForVisa property manually, but no success. The property Set gets called and the INotifyPropertyChanged event gets called, but I am still locked on control and can't navigate.
I have tried calling bindingsource.endedit in the CheckedChanged event, no success.
It only matters if I uncheck the box. The checkbox is two-state - true or false.
All of my other bindings work just fine - text boxes, combo boxes, datagrid. Just not checkbox.
My only thought is that is seems to act like a binding source data error, but no error is thrown. If I add the data error event handler for the binding source, it never gets called.

Assuming the ApplyForVisa property is a Boolean, you can just fix this by setting formattingEnabled parameter for the Binding to False.
chkTableIsReadonly.DataBindings.Add( _
New Binding("Checked", objectBindingSource, "ApplyforVisa", _
False, DataSourceUpdateMode.OnPropertyChanged, False))

Related

how to unload a Form inside a Panel in VB.net

how can i unload a form inside a panel
my code is :
frmInvoiceOverview.Close()
frmInvoiceOverview.Dispose()
With frmInvoiceOverview
.TopLevel = False
MainPanel.Controls.Clear()
MainPanel.Controls.Add(frmInvoiceOverview)
.BringToFront()
.reloadTable()
.Show()
End With
If i "load" it again the Form Load event will not fired.
what do i wrong ?
You are invoking a class like Form doing that which a simply Control (eg. Panel) can do.
That means you have more heavy runtime objects (even not so significant).
However after calling .Dispose in a Form (or whatever else Object) needs to be initialized like
frmInvoiceOverview = New InvoiceOverview With {
.TopLevel = False,
.FormBorderStyle = FormBorderStyle.None}
before calling methods or setting its properties then lifetime cycle restart again

Reaching a control, within a ContentControl from view's code behind

My view's XAML is only containing a custom control.
A bit further, in a Resource Dictionary, I have a Style for this custom control, and inside this, I have a TextBox. My goal would be to reach this TextBox from the view's code behind, and set it's focus, when the view's DataContext changed.
I tried to use x:Name to give a name to the custom control on the view's XAML, and also give a name to the TextBox inside the control's style (so essentially trying to reach it from code behind like: this.MyCustomControl.SearchTextBox). This did not work.
What would be the best practice to solve this issue?
This is what I would do.
Create a TemplatePart attribute on top of your custom control for the TextBox.
[TemplatePart(Name = "YourTextBoxName", Type = typeof(TextBox))]
Then inside the OnApplyTemplate override method, get a reference of the TextBox.
// You might want to add property error handling here
// so if the TextBox is not found, throw an exception.
// Doing so forces other people will have to implement
// the SAME PART in their own stylings.
_textBox = (TextBox)GetTemplateChild("YourTextBoxName");
Then all you need is to create a public method SetFocus that your code behind class can have access to.
public void SetFocus() => _textBox.Focus(FocusState.Programmatic);
Try visual tree helper
VisualTreeHelper.GetChild(object, index)
msdn link

Use control's events if when it is contained in a custom control

I created a custom object, name: MyList.
This Object contains a picturebox and a grid.
I need to do something if the user press on this grid, so i have to "use" MouseDown events of the grid.
I used this event in the MyList project (i can save in a propriety the result for example) but in hosts project can't.
I have only the MouseDown event of the MyList, so if i press on the "form" of the object, this events works, but if i press on the grid of this MyList.
So, i can use MouseDown Event of MyList, but how i can use Grid Events?

Durandal 2.0 Dialog Repositioning

At the bottom of the durandal docs for dialogs / modals (http://durandaljs.com/documentation/Showing-Message-Boxes-And-Modals.html) there's some syntax for repositioning a dialog. The dialog I have gets gradually bigger as the user selects stuff, so every time a selection is made, I'd like to call reposition(). I tried following along with this:
vm.compositionComplete = function (child, parent, context) {
var addEditDialog = dialog.getDialog(context.model); // resolves
// whenever something is selected:
addEditDialog.context.reposition(vm); // no method 'reposition'
}
But I get an error - there is no function reposition. What am I doing wrong?
You can set up a custom dialog context that responds to a reposition message (using Durandal's app.trigger()). You would trigger the message upon some event in your dialog (such as, as you say, the user's selecting stuff).
Also in that custom dialog context, create a method call reposition. In the activate or attached handler of that custom dialog context, subscribe to the message you use to trigger a reposition.
I'm advocating a messaging approach because you may wish to isolate your "selection viewModel" in its own viewModel, and then compose it into your custom dialog context. With this approach, your selection viewModel and your custom dialog context would be loosely bound. That way, you could use your selection viewModel elsewhere in your code (and even have some other viewModel, instead of the custom dialog context, respond to the reposition message).

Windows Forms: Unable to Click to Focus a MaskedTextBox in a Non TopLevel Form

Like the title says, I've got a Child form being shown with it's TopLevel property set to False and I am unable to click a MaskedTextBox control that it contains (in order to bring focus to it). I can bring focus to it by using TAB on the keyboard though.
The child form contains other regular TextBox controls and these I can click to focus with no problems, although they also exhibit some odd behavior: for example if I've got a value in the Textbox and I try to drag-click from the end of the string to the beginning, nothing happens. In fact I can't use my mouse to move the cursor inside the TextBox's text at all (although they keyboard arrow keys work).
I'm not too worried about the odd TextBox behavior, but why can't I activate my MaskedTextBox by clicking on it?
Below is the code that shows the form:
Dim newReportForm As New Form
Dim formName As String
Dim FullTypeName As String
Dim FormInstanceType As Type
formName = TreeView1.SelectedNode.Name
FullTypeName = Application.ProductName & "." & formName
FormInstanceType = Type.GetType(FullTypeName, True, True)
newReportForm = CType(Activator.CreateInstance(FormInstanceType), Form)
Try
newReportForm.Top = CType(SplitContainer1.Panel2.Controls(0), Form).Top + 25
newReportForm.Left = CType(SplitContainer1.Panel2.Controls(0), Form).Left + 25
Catch
End Try
newReportForm.TopLevel = False
newReportForm.Parent = SplitContainer1.Panel2
newReportForm.BringToFront()
newReportForm.Show()
I tried your code and got a good repro this time. As I mentioned in my original post, this is indeed a window activation problem. You can see this in Spy++, note the WM_MOUSEACTIVATE messages.
This happens because you display the form with a caption bar. That convinces the Windows window manager that the window can be activated. That doesn't actually work, it is no longer a top-level window. Visible from the caption bar, it never gets drawn with the "window activated" colors.
You will have to remove the caption bar from the form. That's best done by adding this line to your code:
newReportForm.FormBorderStyle = Windows.Forms.FormBorderStyle.None
Which will turn the form into a control that's otherwise indistinguishable from a UserControl. You can still make it distinctive by using this code instead:
newReportForm.ControlBox = False
newReportForm.Text = ""
Either fix solves the mouse click problem.
This is a miserable bug and it took me a long time to find this question. We're doing exactly the same thing as the OP, displaying a Form inside a split container. My workaround was to add an event handler to the MaskedTextBox's Click event:
private void MaskedTextBoxSetFocus(object sender, EventArgs e)
{
var mtb = (MaskedTextBox)sender;
mtb.Focus();
}
This works for the MaskedTextBox but I'm concerned about other odd behavior due to this bug so I will probably set the border style as in the accepted answer.
The text box behavior is a symptom of the same problem. Something is swallowing mouse down notifications. It isn't explained by your code snippet. Forms indeed swallow the mouse click that activates them, but that is a one-time behavior and is turned off by setting its TopLevel property to False.
Not much left. One candidate is the Control.Capture property, turned on at the MouseDown event for a button so that the button can see the MouseUp event, no matter where the mouse moved. That's a one-time effect as well. Watch out for controls that set the Focus in a MouseDown event.
The other is some kind of IMessageFilter code in your form(s) that's eating WM_LBUTTONDOWN messages.