enter code hereGiven this exmample:
Public Enum Gender
Masculine
Femenine
End Enum
public class ViewModel
private _gender as Gender
Public Property Gender() As Gender
Get
Return _gender
End Get
Set(ByVal value As Gender)
_gender = value
End Set
End Property
end class
Private Sub Form_Load
cmbGender.DataSource = [Enum].GetValues(GetType(Enums.Sexo)) //combobox shows gender ok
cmbGender.DataBindings.Add(New Binding("SelectedItem",ViewModel , "Gender", False, DataSourceUpdateMode.OnPropertyChanged))
end sub
Combobox use ViewModel getter to set its SelectedItem as soon as the Databindings.Add executes but never use the setter when SelectedItem change in the User Interface.
What I am doing wrong?
EDIT
Thanks to Sriram Sakthivel to enlighten me and check combobox events. The final situation is:
Using SelectedItem, DataSourceUpdateMode.OnValidation and combobox.causesValidation = true works when LostFocus raises. If you need onPropertyChanged you should use SelectedIndex and the Sriram Sakthivel's code below.
It will be updated in LostFocus event of ComboBox because SelectedItem doesn't raise change notification (which is necessary for immediate update).
As a workaround you can use SelectedIndex property, which publishes change notification via SelectedIndexChanged event. But there is a problem, SelectedIndex is of type Int32 you need to convert it to Gender and vice versa.
Here's how you'll do that: C# version
private void SetupBinding()
{
var binding = new Binding("SelectedIndex", model, "Gender", true, DataSourceUpdateMode.OnPropertyChanged);
binding.Format += binding_Format;
binding.Parse += binding_Parse;
comboBox1.DataBindings.Add(binding);
}
void binding_Parse(object sender, ConvertEventArgs e)
{
if (e.DesiredType == typeof(Gender))
{
e.Value = comboBox1.Items[(int)e.Value];
}
}
void binding_Format(object sender, ConvertEventArgs e)
{
if (e.DesiredType == typeof(int))
{
e.Value = comboBox1.Items.IndexOf(e.Value);
}
}
Am poor in Vb.net. So I used code converter to convert it to vb.net from c#.
Private Sub SetupBinding()
Dim binding = New Binding("SelectedIndex", model, "Gender", True, DataSourceUpdateMode.OnPropertyChanged)
AddHandler binding.Format, AddressOf binding_Format
AddHandler binding.Parse, AddressOf binding_Parse
comboBox1.DataBindings.Add(binding)
End Sub
Private Sub binding_Parse(sender As Object, e As ConvertEventArgs)
If e.DesiredType = GetType(Gender) Then
e.Value = comboBox1.Items(CInt(e.Value))
End If
End Sub
Private Sub binding_Format(sender As Object, e As ConvertEventArgs)
If e.DesiredType = GetType(Integer) Then
e.Value = comboBox1.Items.IndexOf(e.Value)
End If
End Sub
Related
I have some buttons from User Control(UserCtrl2) and want to dynamically change UserCtrl1,PictureBox BackgroundImage. From my code below, UserCtrl2 PictureBox BackgroundImage property did changed but winform is still showing the previous BackgroundImage.
I have tried the following methods,
me.refresh in UserCtrl1, still nothing happen.
Not sure how to implement {Get and Set} or dispose function.
Thanks in advance for any advise or reference.
Here is my code for UserCtrl1:
Public Class UserCtrl1
Public Sub UserCtrl1_Task(LEDno As UShort, LEDState As Boolean)
Select Case LEDno
Case 0 : Exit Sub
Case 1
If LEDState Then
PicBox_A.BackgroundImage = My.Resources.ResourceManager.GetObject("Blue_ON")
Else
PicBox_A.BackgroundImage = My.Resources.ResourceManager.GetObject("Blue_OFF")
End If
End Select
End Sub
End Class
Here is my Code for UserCtrl2:
Public Class UserCtrl2
Private ButtonClick(4) As Boolean
Private Sub Btn_A_Click(sender As Object, e As EventArgs) Handles Btn_A.Click
Dim InputControl = New UserCtrl1
If Not ButtonClick(0) Then
ButtonClick(0) = True
Btn_A.BackgroundImage = My.Resources.ResourceManager.GetObject("Switch1_ON")
InputControl.UserCtrl1_Task(1, True)
Else
ButtonClick(0) = False
Btn_A.BackgroundImage = My.Resources.ResourceManager.GetObject("Switch1_OFF")
InputControl.UserCtrl1_Task(1, False)
End If
End Sub
End Class
I'm making a Windows Forms application with VB.Net, Visual Studio 2015.
The Form has a WebBrowser control and other controls.
Whenever pressing the TAB key on keyboard, it always focuses on a html element loaded in the WebBrowser control first. Then pressing the TAB key again, the focus is switched between the HTML elements in the WebBrowser control.
Till ending up switching in all HTML elements, the focus doesn't switch to other controls in the Form.
Though I set .TabIndex = 1000 and .TabStop = false in the WebBrowser control, it always focuses on a html element loaded in the WebBrowser control first, always first.
So, I want to disable focusing on the WebBrowser control by pressing the TAB key or to disable the TAB key function in the Form entirely.
I have to get the answer done in VB.NET soon, but for now here's the C# version of it:
First, an extended web browser control, that you'll have to use on the form, with a custom event when the tab key is pressed.
Here we call the TabStop = false to ensure this key gets processed. Similar reasoning on WebBrowserShortcutsEnabled.
Then, we capture on the HTML Body, the key press event.
If the key code is a 9 (tab), we fire our event.
public class WebBrowserExtended : System.Windows.Forms.WebBrowser
{
protected virtual void OnTabKeyEvent(EventArgs e)
{
EventHandler handler = TabKeyEvent;
if (handler != null)
{
handler(this, e);
}
}
public event EventHandler TabKeyEvent;
public WebBrowserExtended() : base()
{
this.TabStop = false;
this.WebBrowserShortcutsEnabled = false;
}
protected override void OnDocumentCompleted(WebBrowserDocumentCompletedEventArgs e)
{
base.OnDocumentCompleted(e);
if (this.Document.Body != null)
this.Document.Body.KeyDown += new HtmlElementEventHandler(Body_KeyDown);
}
private void Body_KeyDown(Object sender, HtmlElementEventArgs e)
{
if (e.KeyPressedCode == 9 && !e.CtrlKeyPressed)
{
this.OnTabKeyEvent(e);
e.BubbleEvent = false;
}
}
}
And here's is your event handler:
private void webBrowser1_TabKeyEvent(object sender, EventArgs e)
{
var controls = new List<Control>(this.Controls.Cast<Control>());
var nextControl = controls.Where(c => c.TabIndex > webBrowser1.TabIndex).OrderBy(c => c.TabIndex).FirstOrDefault();
if (nextControl != null)
nextControl.Focus();
else
controls.OrderBy(c => c.TabIndex).FirstOrDefault().Focus();
}
And here's the VB version of the control:
Public Class WebBrowserExtended
Inherits System.Windows.Forms.WebBrowser
Protected Overridable Sub OnTabKeyEvent(ByVal e As EventArgs)
RaiseEvent TabKeyEvent(Me, e)
End Sub
Public Event TabKeyEvent As EventHandler
Public Sub New()
MyBase.New()
Me.TabStop = False
Me.WebBrowserShortcutsEnabled = False
End Sub
Protected Overrides Sub OnDocumentCompleted(ByVal e As WebBrowserDocumentCompletedEventArgs)
MyBase.OnDocumentCompleted(e)
If Me.Document.Body IsNot Nothing Then
AddHandler Me.Document.Body.KeyDown, AddressOf Body_KeyDown
End If
End Sub
Private Sub Body_KeyDown(ByVal sender As Object, ByVal e As HtmlElementEventArgs)
If e.KeyPressedCode = 9 AndAlso Not e.CtrlKeyPressed Then
Me.OnTabKeyEvent(e)
e.BubbleEvent = False
End If
End Sub
End Class
And the VB event handler:
Private Sub WebBrowser1_TabKeyEvent(sender As Object, e As EventArgs) Handles WebBrowser1.TabKeyEvent
Dim controls = New List(Of Control)(Me.Controls.Cast(Of Control))
Dim nextControl = controls.Where(Function(c)
Return c.TabIndex > WebBrowser1.TabIndex
End Function).OrderBy(Function(c)
Return c.TabIndex
End Function).FirstOrDefault()
If Not controls Is Nothing Then
nextControl.Focus()
Else
controls.OrderBy(Function(c)
Return c.TabIndex
End Function).FirstOrDefault().Focus()
End If
End Sub
Hi i converted the following c# code to vb.net.
public Dropdown(CheckedComboBox ccbParent)
{
this.ccbParent = ccbParent;
InitializeComponent();
this.ShowInTaskbar = false;
this.cclb.ItemCheck += new System.Windows.Forms.ItemCheckEventHandler(this.cclb_ItemCheck);
}
private void cclb_ItemCheck(object sender, ItemCheckEventArgs e)
{
if (ccbParent.ItemCheck != null)
{
ccbParent.ItemCheck(sender, e);
}
}
Visual Basic
Private cclb As CustomCheckedListBox
Public Event ItemCheck As Windows.Forms.ItemCheckEventHandler
Public Sub New(ByVal ccbParent As PlexisCheckedComboBox)
MyBase.New()
Me.ccbParent = ccbParent
InitializeComponent()
Me.ShowInTaskbar = False
AddHandler cclb.ItemCheck, AddressOf cclb_ItemCheck
End Sub
Private Sub cclb_ItemCheck(ByVal sender As Object, ByVal e As
Windows.Forms.ItemCheckEventArgs)
If (Not (ccbParent.ItemCheck) Is Nothing) Then
ccbParent.ItemCheck(sender, e)
End If
End Sub
In the converted vb.net code im getting error in the following line as
""
If (Not (ccbParent.ItemCheck) Is Nothing) Then
ccbParent.ItemCheck(sender, e)
please help me how to resolve it .
Well, as the error message told you, you have to use the RaiseEvent keyword to raise events.
But even then it would not work, since you can't raise events outside of the class the event is declared in (in contrast to C#, where nested classes can raise events of the outer class).
So to solve this add a new method to the outer class called OnItemCheck which raises the ItemCheck event, and call that method in cclb_ItemCheck instead of trying to raise the event directly.
I have a MVC winform app in vb.net,
There is a BaseController which has a reference to a Model, and 2 concreteControllers inherit from this BaseController.
Before InitializeComponent() one controller is instantiated, then InitializeComponent is called and afterwards, some bindings like this one:
chkGeolocalizacion.DataBindings.Add("Checked", controller.Model, "SolicitarGeolocalizacion", False, DataSourceUpdateMode.OnPropertyChanged)
chkGeolocalizacion is inside a groupbox or panel (tried both).
Then the Form waits for user input to choose between 2 radio buttons and an event is triggered, which replaces the controller with the one the user chose. Afterwards I want to make visible the groupbox which has the controls binded and Argumentoutofrangeexception is thrown, with something like "value 0 is not between minimum and maximum".
The code works flawlessly if I never modify the visible property.
Dim modelo As Model_Reporte = controller.Model
If rbtScoringDistancia.Checked Then
controller = New Reporte_controller_SinK()
chkGeolocalizacion.Visible = True
Else
controller = New Reporte_Controller(Me)
chkGeolocalizacion.Visible = False
End If
controller.Model = modelo
pnlConfig.Visible = True
Is this a .net bug or what? I couldn't make it work and the only workaround is to make visible/invisible the controls and not the groupbox or panel that contains them
(I tried with both panel and groupbox, same exception thrown)
Thanks!
ps: if you need to see more of my code ask for it.
edit: Adding extra code
Public Class Reporte
Private controller As Reporte_ControllerBase
Public Sub New()
controller = New Reporte_Controller(Me)
InitializeComponent()
addDataBindings()
End Sub
Private Sub addDataBindings()
dt_fecha_desde.DataBindings.Add("Value", controller.Model, "GetFechaDesde", False, DataSourceUpdateMode.OnPropertyChanged)
dt_fecha_hasta.DataBindings.Add("Value", controller.Model, "GetFechaHasta", False, DataSourceUpdateMode.OnPropertyChanged)
KM_Scoring.DataBindings.Add("Value", controller.Model, "KM_Scoring", False, DataSourceUpdateMode.OnPropertyChanged)
chkGeolocalizacion.DataBindings.Add("Checked", controller.Model, "SolicitarGeolocalizacion", False, DataSourceUpdateMode.OnPropertyChanged)
End Sub
Private Sub rbtScoringDistancia_CheckedChanged(ByVal sender As Object, ByVal e As EventArgs) Handles rbtScoringDistancia.CheckedChanged, rbtScoringAlternativo.CheckedChanged
Dim modelo As Model_Reporte = controller.Model
If rbtScoringDistancia.Checked Then
lblKm.Text = "Iteraciones"
LblScoring.Text = "Considerar infracción a las "
controller = New Reporte_controller_SinK()
chkGeolocalizacion.Visible = True
Else
LblScoring.Text = "Evaluar scoring cada "
lblKm.Text = "Kilómetros"
controller = New Reporte_Controller(Me)
chkGeolocalizacion.Visible = False
End If
controller.Model = modelo
pnlConfig.Visible = True 'Exception thrown here
End Sub
End Class
Public Class Reporte_Controller
Inherits Reporte_ControllerBase
'extra code...
End Class
Public MustInherit class Reporte_ControllerBase
Protected modelo As Model_Reporte = New Model_Reporte
Public Property Model() As Model_Reporte
Get
Return modelo
End Get
Set(ByVal value As Model_Reporte)
modelo = value
End Set
End Property
End Class
Public Class Model_Reporte
Private _getFechaDesde As Date = Date.Today.AddMonths(-1)
Private _getfechaHasta As Date = Date.Today
Private _kmScoring As Integer
Private _solicitarGeolocalizacion As Boolean
Private _limiteRegular As Int32 = 7
Private _limiteMal As Int32 = 25
'getters and setters for each property
End Class
to clarify: Everything works except making the panel visible property on true if I set it false before. If it is true and I don't modify it, it works.
edit2: The exception is only thrown when making visible = true on panels or groupbox which have several controls binded to the model of a controller. Making visible = true or false on another groupbox which contains controls NOT binded works flawlessly.
I fixed this error by adding the databinding in the form_load event rather than adding them in the new (after InitializeComponents() is called). It's weird I know but this solved the issue.
Does anyone know why the Listbox1.Refresh() command may not trigger the ListBox1_DrawItem sub every time?
In Microsoft Visual Basic 2010, a listbox has a forcolor and backcolor property. These properties change the forcolour and backcolor for all the items in the listbox. By default there is no property for the forecolor and backcolor of an individual item on a listbox, I am aware there is on a list view but I would still wish to use a listbox.
I am trying to have the ability to change the forecolor and backcolor properties of individual items in the listbox.
To do this the listbox's draw item sub must be used with the listbox's drawmode property set to OwnerDrawFixed. Then using a brush colour along with the e.graphics the forecolor or backcolor can be changed.
I have seen and followed examples of how to do this for the currently selected item. Such as the one from ehow's website.
What I am tiring to do however is change the colour of the litsbox item as it is added depending on a variable.
Here is my code:
Private Sub listbox_add()
Me.ListBox1.Items.Add(listbox_text(list_num)) ' adds the line to the list box
add_item_colour = True
ListBox1.Refresh()
End Sub
Private Sub ListBox1_DrawItem(ByVal sender As Object, ByVal e As System.Windows.Forms.DrawItemEventArgs) Handles ListBox1.DrawItem
Dim myBrush As Brush = Brushes.Black
e.DrawBackground()
If add_item_colour = True Then
If blue_message = True Then
myBrush = Brushes.Blue
Else
myBrush = Brushes.Black
End If
e.Graphics.DrawString(ListBox1.Items.Item(list_num), ListBox1.Font, myBrush, _
New RectangleF(e.Bounds.X, e.Bounds.Y, e.Bounds.Width, e.Bounds.Height))
add_item_colour = False
End If
e.DrawFocusRectangle()
End Sub
The listbox_text is a string array that stores the string being added, the list_num is a integer that increments when new items are added to the listbox and the blue_message is a Boolean that it true when I want a blue message and false when I don't.
The problem I seem to be having is that Listbox1.Refresh() command does not seem to be triggering the ListBox1_DrawItem sub every time it is called. I found this by using brake points. Does anyone know why this might be the case and how I could fix it?
Thanks, any help on this would be much appreciated.
First of all I suggest you to use background worker instead of directly writing down your code on UI thread.
Please refer the code below:
public partial class Form1 : Form
{
Brush myBrush = Brushes.Blue;
public Form1()
{
InitializeComponent();
this.backgroundWorker1.DoWork += backgroundWorker1_DoWork;
this.backgroundWorker1.RunWorkerCompleted += backgroundWorker1_RunWorkerCompleted;
this.backgroundWorker1.RunWorkerAsync(this);
}
private void listBox1_DrawItem(object sender, DrawItemEventArgs e)
{
e.DrawBackground();
e.Graphics.DrawString(listBox1.Items[e.Index].ToString(), listBox1.Font, myBrush, new RectangleF(e.Bounds.X, e.Bounds.Y, e.Bounds.Width, e.Bounds.Height));
e.DrawFocusRectangle();
}
private void button1_Click(object sender, EventArgs e)
{
this.backgroundWorker1.RunWorkerAsync(button1);
}
private void button2_Click(object sender, EventArgs e)
{
this.backgroundWorker1.RunWorkerAsync(button2);
}
void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
this.listBox1.Refresh();
}
void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
if (e.Argument == this)
{
listBox1.Items.Add("p1");
listBox1.Items.Add("p2");
}
else if (e.Argument == this.button1)
{
myBrush = Brushes.Red;
listBox1.Refresh();
}
else if (e.Argument == this.button2)
{
myBrush = Brushes.Green;
if (listBox1.SelectedItem == null)
return;
var test = listBox1.Items[listBox1.SelectedIndex];
listBox1.SelectedItem = test;
var g = listBox1.CreateGraphics();
var rect = listBox1.GetItemRectangle(listBox1.SelectedIndex);
listBox1_DrawItem(listBox1, new DrawItemEventArgs(g, this.Font, rect, listBox1.SelectedIndex, DrawItemState.Default));
listBox1.Refresh();
}
}
}