Can't find the answer to a seemingly easy question. I need to iterate through the controls on a form, and if a control is a CheckBox, and is checked, certain things should be done. Something like this
foreach (Control c in this.Controls)
{
if (c is CheckBox)
{
if (c.IsChecked == true)
// do something
}
}
But I can't reach the IsChecked property.
The error is 'System.Windows.Forms.Control' does not contain a definition for 'IsChecked' and no extension method 'IsChecked' accepting a first argument of type 'System.Windows.Forms.Control' could be found (are you missing a using directive or an assembly reference?)
How can I reach this property? Thanks a lot in advance!
EDIT
Okay, to answer all - I tried casting, it doesn't work.
You're close. The property you're looking for is Checked
foreach (Control c in this.Controls) {
if (c is CheckBox) {
if (((CheckBox)c).Checked == true)
// do something
}
}
You need to cast it to checkbox.
foreach (Control c in this.Controls)
{
if (c is CheckBox)
{
if ((c as CheckBox).IsChecked == true)
// do something
}
}
You have to add a cast from Control to CheckBox:
foreach (Control c in this.Controls)
{
if (c is CheckBox)
{
if ((c as CheckBox).IsChecked == true)
// do something
}
}
You need to cast the control:
foreach (Control c in this.Controls)
{
if (c is CheckBox)
{
if (((CheckBox)c).IsChecked == true)
// do something
}
}
The Control class does not define an IsChecked property, so you will need to cast it to the appropriate type first:
var checkbox = c as CheckBox;
if( checkbox != null )
{
// 'c' is a CheckBox
checkbox.IsChecked = ...;
}
Related
I have a Winform project in VB.net 2013.
On a form I have a lot's of controls.
When a condition is true , I need to make all the controls inside a specific form's area , not clickable ( but without disabling them )
Of course , when the condition became false the area should return to normal state.
Thank you !
You could assign a NativeWindow to each control and intercept the HITTEST message.
E.g. This example only does it for the immediate Form's children. You could also recurse through all the children.
Form f = new Form();
f.Controls.Add(new Button { Text = "test test test "});
Form f2 = new Form();
CheckBox cb = new CheckBox { Text = "Toggle" };
f2.Controls.Add(cb);
List<NW> nws = null;
cb.CheckedChanged += delegate {
if (nws == null) {
nws = new List<NW>();
foreach (Control c in f.Controls) {
nws.Add(new NW(c.Handle));
}
}
else {
foreach (var nw in nws)
nw.ReleaseHandle();
nws = null;
}
};
f.Show();
Application.Run(f2);
class NW : NativeWindow {
public NW(IntPtr hwnd) {
AssignHandle(hwnd);
}
const int WM_NCHITTEST = 0x84;
protected override void WndProc(ref Message m) {
if (m.Msg == WM_NCHITTEST)
return;
base.WndProc(ref m);
}
}
Place all controls in a PANEL and then disable that panel.
panel.Enabled= false;
Checking and unchecking of a checkbox using Selenium WebDriver.
I am using the page object pattern, so my code appears this way.
SelectCheckBox("Check"); OR SelectCheckBox("Uncheck");
[FindsBy(How = How.Id, Using = "payment_sameasdeliveryaddress")]
public IWebElement checkbox_Address = null;
public void SetCheckBox(string value)
{
//Console.Write("checkbox state: " + checkbox_Address.Selected);
if (value.ToLower().Equals("uncheck") && checkbox_Address.Selected)
{
checkbox_Address.Click();
}
else if (value.ToLower().Equals("check") && !checkbox_Address.Selected)
{
checkbox_Address.Click();
}
It has been years since I wrote any .NET, so the below may not even compile! But hopefully you get the idea.
// The individual elements should be declared private
private IWebElement payment_sameasdeliveryaddress;
// If you name it same as the source element
// ID, PageFactory will find it for you
// flag = true, means you want it checked
public void SelectCheckBox(Boolean check)
{
if (!check && payment_sameasdeliveryaddress.Selected) {
payment_sameasdeliveryaddress.Click();
}
else if (check && !payment_sameasdeliveryaddress.Selected) {
payment_sameasdeliveryaddress.Click();
}
The simplest way of checking a checkbox is checked or not by using the isSelected() method with an element. For example:
if(getCheckBox().isSelected()){
getCheckBox.click();
}
public WebElement getCheckBox(){
return driver.findElement(termsCheck);
}
This would also work:
// flag = true, means you want it checked
public void SelectCheckBox(Boolean check)
{
if (check ^ payment_sameasdeliveryaddress.Selected) {
payment_sameasdeliveryaddress.Click();
}
}
Sharing the snippet that's just implemented in the current project using Selenium WebDriver 3.9.1 and TestNG 6.14.
// Returns boolean value based on whether check-box is selected or not
Boolean chkBx1Sel = driver.findElement(By.xpath(elementXpath)).isSelected();
Case 1: Check a check-box
if(dataValofChkBx != null && dataValofChkBx.equalsIgnoreCase("Y"))
{
if(chkBx1Sel.toString() == "false") //i.e., checkbox is not already checked
{
driver.findElement(By.xpath(POP2GUIConstants.ggsnFwlfUpdChkBx)).click();
}
}
Case 2: Uncheck a check-box
if(dataValofChkBx != null && dataValofChkBx.equalsIgnoreCase("N"))
{
if(chkBx1Sel.toString() == "true") // I.e., checkbox is already checked
{
driver.findElement(By.xpath(POP2GUIConstants.ggsnFwlfUpdChkBx)).click();
}
}
Goal
I want to display the text that I put in the Label's "Error on ErrorProvider1" attribute whenever I get an error. See the following label's attributes below.
I try to display the text in the red rectangle into my ErrorProvider1 SetError(control, value) function.
If TextBox1.Text.Trim.Contains("'") Then
ErrorProvider1.SetError(lblErr, ErrorProvider1.GetError(lblErr))
Else
ErrorProvider1.SetError(lblErr, "")
End If
How can I retrieve the 'Error on ErrorProvider1' text from the lblErr to display it in the ErrorProvider1 SetError value?
The ErrorProvider component is very awkward to use effectively. It is fixable however, I'll give an example in C# that extends the component with some new capabilities:
ShowError(Control ctl, bool enable) displays the text that you entered at design-time when the enable argument is true. The easier-to-use version of SetError().
HasErrors returns true if the any active warning icons are displayed. Handy in your OK button's Click event handler.
FocusError() sets the focus to the first control that has a warning icon, if any. It returns false if no warnings are remaining.
SetError() is a replacement of ErrorProvider.SetError(). You only need it if you add any controls after the form's Load event fired or if you need to modify the warning text.
Add a new class to your project and paste the code shown below. Compile. Drop it from the top of the toolbox onto the form. The design-time behavior is identical. Modestly tested.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows.Forms;
using System.ComponentModel.Design;
class MyErrorProvider : ErrorProvider {
public void ShowError(Control ctl, bool enable) {
// Easy to use version of SetError(), uses design-time text
if (!enable) base.SetError(ctl, "");
else {
if (errors.ContainsKey(ctl)) base.SetError(ctl, errors[ctl]);
else base.SetError(ctl, "No error text available");
}
}
public bool HasErrors {
// True if any errors are present
get {
foreach (var err in errors)
if (!string.IsNullOrEmpty(base.GetError(err.Key))) return true;
return false;
}
}
public bool FocusError() {
// Set the focus to the first control with an active error
foreach (var err in errors) {
if (!string.IsNullOrEmpty(base.GetError(err.Key))) {
err.Key.Focus();
return true;
}
}
return false;
}
public new void SetError(Control ctl, string text) {
// Use this only to add/modify error text after the form's Load event
if (!string.IsNullOrEmpty(text)) {
if (errors.ContainsKey(ctl)) errors[ctl] = text;
else errors.Add(ctl, text);
}
base.SetError(ctl, text);
}
private void initialize(object sender, EventArgs e) {
// Preserve error text
copyErrors(((Form)sender).Controls);
}
private void copyErrors(Control.ControlCollection ctls) {
foreach (Control ctl in ctls) {
var text = this.GetError(ctl);
if (!string.IsNullOrEmpty(text)) {
errors.Add(ctl, text);
base.SetError(ctl, "");
}
copyErrors(ctl.Controls);
}
}
private Dictionary<Control, string> errors = new Dictionary<Control, string>();
// Plumbing to hook the form's Load event
[Browsable(false)]
public new ContainerControl ContainerControl {
get { return base.ContainerControl; }
set {
if (base.ContainerControl == null) {
var form = value.FindForm();
if (form != null) form.Load += initialize;
}
base.ContainerControl = value;
}
}
public override ISite Site {
set {
// Runs at design time, ensures designer initializes ContainerControl
base.Site = value;
if (value == null) return;
IDesignerHost service = value.GetService(typeof(IDesignerHost)) as IDesignerHost;
if (service == null) return;
IComponent rootComponent = service.RootComponent;
this.ContainerControl = rootComponent as ContainerControl;
}
}
}
Your issue is that you are replacing the error message when nothing is wrong. As noted in your comment below, you are storing the localized error message in the label's Tag, so you can do the following:
If TextBox1.Text.Trim.Contains("'") Then
ErrorProvider1.SetError(lblErr, lblErr.Tag)
Else
ErrorProvider1.SetError(lblErr, "")
End If
You were correct to use ErrorProvider1.GetError(Control) to get the value. It's just that you're more than likely replacing it with an empty string before you were retrieving it.
In XAML and WinRT, Is there a way to set up a textbox so that it is disabled for text input until it is tapped.
I tried setting up the Tapped event and then setting the IsEnabled=true, but that only seems to work if the IsEnabled=true in the first place.
I found this on MSDN:
http://social.msdn.microsoft.com/Forums/en-US/winappswithcsharp/thread/708c0949-8b06-40ec-85fd-201139ca8b2d
Talks about adding the TappedEvent manually to the event handled for each TextBox, which is cumbersome, but also doesn't seem to work unless IsEnabled was already set to true.
Basically, I want a form where all textboxes display data but are disabled unless the user taps to enable the box and then type.
You can use IsReadOnly instead of IsEnabled to achieve what you are looking for. In addition, you can set up the tapped event handlers in code easily. I'm not sure if setting up handlers in code is a requirement for this to work, as you noted above; however, it does simplify things.
Here are the details.
In the constructor of your page class (here it is MainPage), call the setup function:
public MainPage()
{
this.InitializeComponent();
// call the setup for the textboxes
SetupTextBoxes();
}
Here is where we do the magic - make all textboxes on this page readonly and set up tap handler:
private void SetupTextBoxes()
{
var tbs = GetVisualChildren<TextBox>(this, true);
foreach (var tb in tbs)
{
tb.IsReadOnly = true;
tb.AddHandler(TappedEvent, new TappedEventHandler(tb_Tapped), true);
}
}
Utility function to get a list of all children of the given type (T) of the passed in parent.
private List<T> GetVisualChildren<T>(DependencyObject parent, bool recurse = true)
where T : DependencyObject
{
var children = new List<T>();
int numVisuals = VisualTreeHelper.GetChildrenCount(parent);
for (int i = 0; i < numVisuals; i++)
{
DependencyObject v = (DependencyObject)VisualTreeHelper.GetChild(parent, i);
var child = v as T;
if (child == null && recurse)
{
var myChildren = GetVisualChildren<T>(v, recurse);
children.AddRange(myChildren);
}
if (child != null)
children.Add(child);
}
return children;
}
Finally, the event handler. This enables each textbox when tapped.
private void tb_Tapped(object sender, TappedRoutedEventArgs e)
{
((TextBox)(sender)).IsReadOnly = false;
}
Do anyone have good ideas of how to modify the toolbar for the WinForms version of the ReportViewer Toolbar?
That is, I want to remove some buttons and varius, but it looks like the solution is to create a brand new toolbar instead of modifying the one that is there.
Like, I had to remove export to excel, and did it this way:
// Disable excel export
foreach (RenderingExtension extension in lr.ListRenderingExtensions()) {
if (extension.Name == "Excel") {
//extension.Visible = false; // Property is readonly...
FieldInfo fi = extension.GetType().GetField("m_isVisible", BindingFlags.Instance | BindingFlags.NonPublic);
fi.SetValue(extension, false);
}
}
A bit trickysh if you ask me..
For removing toolbarbuttons, an possible way was to iterate through the Control array inside the ReportViewer and change the Visible property for the buttons to hide, but it gets reset all the time, so it is not an good way..
WHEN do MS come with an new version btw?
Yeap. You can do that in a little tricky way.
I had a task to add more scale factors to zoom report. I did it this way:
private readonly string[] ZOOM_VALUES = { "25%", "50%", "75%", "100%", "110%", "120%", "125%", "130%", "140%", "150%", "175%", "200%", "300%", "400%", "500%" };
private readonly int DEFAULT_ZOOM = 3;
//--
public ucReportViewer()
{
InitializeComponent();
this.reportViewer1.ProcessingMode = ProcessingMode.Local;
setScaleFactor(ZOOM_VALUES[DEFAULT_ZOOM]);
Control[] tb = reportViewer1.Controls.Find("ReportToolBar", true);
ToolStrip ts;
if (tb != null && tb.Length > 0 && tb[0].Controls.Count > 0 && (ts = tb[0].Controls[0] as ToolStrip) != null)
{
//here we go if our trick works (tested at .NET Framework 2.0.50727 SP1)
ToolStripComboBox tscb = new ToolStripComboBox();
tscb.DropDownStyle = ComboBoxStyle.DropDownList;
tscb.Items.AddRange(ZOOM_VALUES);
tscb.SelectedIndex = 3; //100%
tscb.SelectedIndexChanged += new EventHandler(toolStripZoomPercent_Click);
ts.Items.Add(tscb);
}
else
{
//if there is some problems - just use context menu
ContextMenuStrip cmZoomMenu = new ContextMenuStrip();
for (int i = 0; i < ZOOM_VALUES.Length; i++)
{
ToolStripMenuItem tsmi = new ToolStripMenuItem(ZOOM_VALUES[i]);
tsmi.Checked = (i == DEFAULT_ZOOM);
//tsmi.Tag = (IntPtr)cmZoomMenu;
tsmi.Click += new EventHandler(toolStripZoomPercent_Click);
cmZoomMenu.Items.Add(tsmi);
}
reportViewer1.ContextMenuStrip = cmZoomMenu;
}
}
private bool setScaleFactor(string value)
{
try
{
int percent = Convert.ToInt32(value.TrimEnd('%'));
reportViewer1.ZoomMode = ZoomMode.Percent;
reportViewer1.ZoomPercent = percent;
return true;
}
catch
{
return false;
}
}
private void toolStripZoomPercent_Click(object sender, EventArgs e)
{
ToolStripMenuItem tsmi = sender as ToolStripMenuItem;
ToolStripComboBox tscb = sender as ToolStripComboBox;
if (tscb != null && tscb.SelectedIndex > -1)
{
setScaleFactor(tscb.Items[tscb.SelectedIndex].ToString());
}
else if (tsmi != null)
{
if (setScaleFactor(tsmi.Text))
{
foreach (ToolStripItem tsi in tsmi.Owner.Items)
{
ToolStripMenuItem item = tsi as ToolStripMenuItem;
if (item != null && item.Checked)
{
item.Checked = false;
}
}
tsmi.Checked = true;
}
else
{
tsmi.Checked = false;
}
}
}
Get the toolbar from ReportViewer control:
ToolStrip toolStrip = (ToolStrip)reportViewer.Controls.Find("toolStrip1", true)[0]
Add new items:
toolStrip.Items.Add(...)
There are a lot of properties to set which buttons would you like to see.
For example ShowBackButton, ShowExportButton, ShowFindControls, and so on. Check them in the help, all starts with "Show".
But you are right, you cannot add new buttons. You have to create your own toolbar in order to do this.
What do you mean about new version? There is already a 2008 SP1 version of it.
Another way would be to manipulate the generated HTML at runtime via javascript. It's not very elegant, but it does give you full control over the generated HTML.
For VS2013 web ReportViewer V11 (indicated as rv), the code below adds a button.
private void AddPrintBtn()
{
foreach (Control c in rv.Controls)
{
foreach (Control c1 in c.Controls)
{
foreach (Control c2 in c1.Controls)
{
foreach (Control c3 in c2.Controls)
{
if (c3.ToString() == "Microsoft.Reporting.WebForms.ToolbarControl")
{
foreach (Control c4 in c3.Controls)
{
if (c4.ToString() == "Microsoft.Reporting.WebForms.PageNavigationGroup")
{
var btn = new Button();
btn.Text = "Criteria";
btn.ID = "btnFlip";
btn.OnClientClick = "$('#pnl').toggle();";
c4.Controls.Add(btn);
return;
}
}
}
}
}
}
}
}
I had this question for al ong time I I found the answer after a long tie and the main source of kowledge I used was this webpega: I'd like to thank you all guys adding the code that allowed me to do it and a picture with the result.
Instead of using the ReportViewer Class, you need to create a new classs, in my case, I named it ReportViewerPlus and it goes like this:
using Microsoft.Reporting.WinForms;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace X
{
class ReportViewerPlus : ReportViewer
{
private Button boton { get; set; }
public ReportViewerPlus(Button but) {
this.boton = but;
testc(this.Controls[0]);
}
public ReportViewerPlus()
{
}
private void testc(Control item){
if(item is ToolStrip)
{
ToolStripItemCollection tsic = ((ToolStrip)item).Items;
tsic.Insert(0, new ToolStripControlHost(boton));
return;
}
for (int i = 0; i < item.Controls.Count; i++)
{
testc(item.Controls[i]);
}
}
}
}
You have to add the button directly in the constructor of the class and you can configure the button in your designer.
Here's a pic of the result, not perfect, but enough to go(safe link I swear, but I can't post my own pics, don't have enough reputation).
http://prntscr.com/5lfssj
If you look carefully in the code of the class, you'd see more or less how it works and you could make your changes and make it possible to establish it in other site of the toolbar.
Thank you so much for helping me in the past, I hope this helps lots of people!
Generally you are suppose to create your own toolbar if you want to modify it. Your solution for removing buttons will probably work if that is all you need to do, but if you want to add your own you should probably just bite the bullet and build a replacement.
You may modify reportviewer controls by CustomizeReportToolStrip method.
this example remove Page Setup Button, Page Layout Button in WinForm
public CustOrderReportForm() {
InitializeComponent();
CustomizeReport(this.reportViewer1);
}
private void CustomizeReport(Control reportControl, int recurCount = 0) {
Console.WriteLine("".PadLeft(recurCount + 1, '.') + reportControl.GetType() + ":" + reportControl.Name);
if (reportControl is Button) {
CustomizeReportButton((Button)reportControl, recurCount);
}
else if (reportControl is ToolStrip) {
CustomizeReportToolStrip((ToolStrip)reportControl, recurCount);
}
foreach (Control childControl in reportControl.Controls) {
CustomizeReport(childControl, recurCount + 1);
}
}
//-------------------------------------------------------------
void CustomizeReportToolStrip(ToolStrip c, int recurCount) {
List<ToolStripItem> customized = new List<ToolStripItem>();
foreach (ToolStripItem i in c.Items) {
if (CustomizeReportToolStripItem(i, recurCount + 1)) {
customized.Add(i);
}
}
foreach (var i in customized) c.Items.Remove(i);
}
//-------------------------------------------------------------
void CustomizeReportButton(Button button, int recurCount) {
}
//-------------------------------------------------------------
bool CustomizeReportToolStripItem(ToolStripItem i, int recurCount) {
Console.WriteLine("".PadLeft(recurCount + 1, '.') + i.GetType() + ":" + i.Name);
if (i.Name == "pageSetup") {
return true;
}
else if (i.Name == "printPreview") {
return true;
}
return false; ;
}