Does data binding work on invisible control? - c#

This is a .net problem with winforms, not asp.net.
I have a windows form with several tabs. I set data bindings of all controls when the form is loaded. But I have noticed that the data bindings of controls on the second tab do not work. Those bindings work only when the form is loaded and when I select the second tab. This brings the suspicion to me: data bindings work only when bound controls become visible.
Anyone can tell me whether this is true or not? It is not hard to test this but I would like to know some confirmation.
Thanks

You are correct. A data-bound control are not updated until the control is made visible.
The only reference I can find for this at the moment is this MSDN thread.

Your issue has to do with the behavior of the TabControl. See Microsoft bug report. I posted a workaround for that problem which subclasses the TabControl and 'Iniatalizes' all the tab pages when the control is created or the handle is created. Below is the code for the workaround.
public partial class TabControl : System.Windows.Forms.TabControl
{
protected override void OnHandleCreated(EventArgs e_)
{
base.OnHandleCreated(e_);
foreach (System.Windows.Forms.TabPage tabPage in TabPages)
{
InitializeTabPage(tabPage, true, Created);
}
}
protected override void OnControlAdded(ControlEventArgs e_)
{
base.OnControlAdded(e_);
System.Windows.Forms.TabPage page = e_.Control as System.Windows.Forms.TabPage;
if ((page != null) && (page.Parent == this) && (IsHandleCreated || Created))
{
InitializeTabPage(page, IsHandleCreated, Created);
}
}
protected override void OnCreateControl()
{
base.OnCreateControl();
foreach (System.Windows.Forms.TabPage tabPage in TabPages)
{
InitializeTabPage(tabPage, IsHandleCreated, true);
}
}
//PRB: Exception thrown during Windows Forms data binding if bound control is on a tab page with uncreated handle
//FIX: Make sure all tab pages are created when the tabcontrol is created.
//https://connect.microsoft.com/VisualStudio/feedback/details/351177
private void InitializeTabPage(System.Windows.Forms.TabPage page_, bool createHandle_, bool createControl_)
{
if (!createControl_ && !createHandle_)
{
return;
}
if (createHandle_ && !page_.IsHandleCreated)
{
IntPtr handle = page_.Handle;
}
if (!page_.Created && createControl_)
{
return;
}
bool visible = page_.Visible;
if (!visible)
{
page_.Visible = true;
}
page_.CreateControl();
if (!visible)
{
page_.Visible = false;
}
}
}

We've encountered a similar problem. We're trying to write to 2 bound, invisible fields so that we can change the format that we write to our dataset. This works fine when the objects are visible, but stops working when the visible property was changed to false.
To get round it, I added the following code:
// Stop our screen flickering.
chSplitContainer.Panel2.SuspendLayout();
// Make the bound fields visible or the binding doesn't work.
tbxValueCr.Visible = true;
tbxValueDb.Visible = true;
// Update the fields here.
<DO STUFF>
// Restore settings to how they were, so you don't know we're here.
tbxValueCr.Visible = false;
tbxValueDb.Visible = false;
chSplitContainer.Panel2.ResumeLayout();

I've struggled with this myself and concluded that the only workaround, besides subclassing apparently (see hjb417's answer), was to make the other tab visible. Switching to the other tab and going back to the previous immediately before the form is visible doesn't work. If you do not want to have the second tab visible, I've used the following code as a workaround:
this.tabControl.SelectedTab = this.tabPageB;
this.tabPageB.BindingContextChanged += (object sender, EventArgs e) => {
this.tabContainerMain.SelectedTab = this.tabPageA;
};
Assuming tabPageA is the visible tab, and tabPageB is the invisible one you want to initialize. This switches to pageB, and switches back once the data binding is complete. This is invisible to the user in the Form.
Still an ugly hack, but at least this works. Off course, he code gets even uglier when you have multiple tabs.

Sorry for necromancing this thread, but it is easy to force the invisible controls' databinding/handles to be ready using this method:
https://social.msdn.microsoft.com/Forums/vstudio/en-US/190296c5-c3b1-4d67-a4a7-ad3cdc55da06/problem-with-binding-and-tabcontrol?forum=winforms
Simply, let's say if your controls are in tab page tpg_Second (or tabCtl.TabPages[1]), before you do anything with their data, call this first:
tpg_Second.Show()
This will not activate any of the tab pages, but viola, the databinding of the controls should work now.

This is not something I've come across directly. However, you might be experiencing a problem with the BindingContext. Without more details it's hard to say, but if I were you I'd set a breakpoint and make sure the controls are all bound in the same context.

Based on the answers, I made this method that works for me:
public partial class Form1: Form
{
private void Form1_Load(object sender, EventArgs e)
{
...
forceBindTabs(tabControl1);
}
private void forceBindTabs(TabControl ctl)
{
ctl.SuspendLayout();
foreach (TabPage tab in ctl.TabPages)
tab.Visible = true;
ctl.ResumeLayout();
}
}
In addition to solving the problem, the tabs are loaded at the beginning and are displayed faster when the user clicks on them.

Related

Implement form level shortcuts without intercept child control's input

I'm making form level shortcuts with form application.
First, it works with strip menus, however their shortcuts must be combination of any modifier and a word or decimal key. I need only a word or decimal key shortcut. Therefore it does not fit my needs.
And I tried a method that KeyDown and KeyUp events with form's KeyPreview set to true. If I handled the word or decimal keys with Handled and SuppressKeyPress set to true in those events, the child control cannot receive the input even though the control is TextBox or NumericUpDown that is a control that allows text input. Overriding ProcessCmdKey has the same issue.
And then, I tried to check the focusing control actually needs the input by calling focusing control's IsInputKey and IsInputChar. Yes, you cannot call them normally because these methods are protected. I used reflection. But I had no luck. These were not working as I expected.
Finally, I applied a branch that checks the focusing control is TextBox or something allowing input. I had no luck with this either. Because the NumericUpDown's real focus control is a private class called UpDownBase.UpDownEdit. It means that some other controls can have similar mechanism that cannot expect in build time. In short, it can cause bugs.
I think, I could solve this issue if there was a way to catch unhandled input in last key handling phase such like bubbling. But I couldn't find information about it for form applications.
Do I have to override ALL of child controls' ProcessCmdKeys?
Really isn't there a fancy way to solve this problem?
Here is my quick solution. I have changed searching focused control method.
In previous, it searching to the deepest active control. The source was from here. This way caused skipping NumericUpDown case because it is also a container, and returned its private control.
Therefore, I have changed it to searching a control type instead taking the deepest one in active control chain.
static bool IsFocusedControlType<T>(Control control, out T focused)
where T : Control
{
if (control is T t)
{
focused = t;
return true;
}
var container = control as IContainerControl;
while (container != null)
{
control = container.ActiveControl;
if (control is T tt)
{
focused = tt;
return true;
}
container = control as IContainerControl;
}
focused = null;
return false;
}
static bool CanConsumeKey(Form sender, KeyEventArgs e)
{
if (IsFocusedControlType(sender, out NumericUpDown ud))
{
return false;
}
if (IsFocusedControlType(sender, out TextBox tb) && !tb.ReadOnly)
{
return false;
}
if (IsFocusedControlType(sender, out ListView lv) && lv.LabelEdit)
{
return false;
}
if (IsFocusedControlType(sender, out TreeView tv) && tv.LabelEdit)
{
return false;
}
if (IsFocusedControlType(sender, out ComboBox cb) &&
cb.DropDownStyle != ComboBoxStyle.DropDownList)
{
return false;
}
return true;
}
It works fine but I don't think it's fast.

Check if data has changed after setting binding source

I use a binding source so that all my controls are bound to datasource. Like this:
var category = categoryRequest.Get(id);
bindingSource.DataSource = category;
This works fine.
I've also implemented INotifyPropertyChanged on the DTO classes (even though this should not be done), so that a change in the object's properties is reflected immediately in the corresponding controls. This also works.
However, if the user loads an object, changes some text in some controls and decides to close the form, I would like to determine if data has been changed and prompt a "Are you sure?" message.
Currently, the way I'm doing it is like this:
public static bool DataChanged(this Form form)
{
bool changed = false;
if (form == null)
return changed;
foreach (Control c in form.Controls)
{
switch (c.GetType().ToString())
{
case "TextBox":
changed = ((TextBox)c).Modified;
break;
//Other control types here...
}
if (changed)
break;
}
return changed;
}
But I don't think this is the best way to do it because:
Each control type needs to the added manually
Checking if lists have changed won't work
Is there a better way to achieve what I need?
Do you want to check it only once? Like before closing the window.. If you do you can
declare public static bool changed=false; in the form class and change its value to true from where you have implimented the INotifyPropertychanged.
you can display a messagebox anywhere in the form as follows.
if(changed)
{
if (MessageBox.Show("Are you sure?","some caption",MessageBoxButtons.YesNo)==DialogResult.Yes)
{
//Do this if user presses YES
}
}
I realize this is an older thread, but I would suggest a simple solution:
if (YourTextBox.Modified)
{
// Your code goes here.
}
I think it has been around since version 1.0. You will find further information here.
Just subscribe to the BindingSource's ListChanged event and set an IsDirty flag based on the event.
categoryBindingSource.ListChanged += new System.ComponentModel.ListChangedEventHandler(categoryBindingSource_ListChanged);
and set IsDirty = true in the event method...
void customerAccountBindingSource_ListChanged(object sender, system.ComponentModel.ListChangedEventArgs e)
{
if (e.ListChangedType == System.ComponentModel.ListChangedType.ItemChanged)
_isDirty = true;
}

Managing EventHandlers within a large Form

I'm developing a WinForm application and I've done a pretty bad job thus far of managing the size and contents. I was hoping someone could give me an example of how to break out some of the logic that I have within the main form cs file.
Here is an example of an EventHandler function that I have within my MainWindow.cs:
private void GroupBoxRequestTypeCheckedChanged(object pSender, EventArgs pEventArgs)
{
RadioButton vRadioButton = pSender as RadioButton;
if (vRadioButton != null)
{
this.fSelectedButton = vRadioButton.Checked ? vRadioButton : null;
if (vRadioButton.Equals(this.RadioButton_Copy) || vRadioButton.Equals(this.RadioButton_Delete) || vRadioButton.Equals(this.RadioButton_Download)
|| vRadioButton.Equals(this.RadioButton_Move) || vRadioButton.Equals(this.RadioButton_Upload))
{
this.GroupBox_Files.Enabled = true;
this.GroupBox_Variables.Enabled = false;
}
else
{
this.GroupBox_Files.Enabled = false;
this.GroupBox_Variables.Enabled = true;
}
if (this.fSelectedButton != null)
{
if (this.fSelectedButton.Equals(this.RadioButton_Delete))
{
this.TextBox_DestinationFile.Enabled = false;
this.Button_DestinationBrowse.Enabled = false;
}
else
{
this.TextBox_DestinationFile.Enabled = true;
this.Button_DestinationBrowse.Enabled = true;
}
}
}
}
So this is simply one of many EventHandler's that I have within a Form. I created a MainForm which has a Tabbed Pane and has a collection of Tabs which have buttons, textboxes, checkboxes etc in each tab. All of the events that I handle go into the MainForm.cs file and now I've got close to 1,000 lines in this one file.
Can someone give me a simple example (or a article/document) detailing good structure? Can I define my EventHandler functions in a separate class (if so, how would this work...) Do I create some sort of static Helper class where I simply pass the instance of the objects i need to manipulate? I.E.
private void GroupBoxRequestTypeCheckedChange(object pSender, EventArgs pEventArgs)
{
HelperClass.HandleGroupBoxRequestTypeCheckedChanged(pSender, pEventArgs, this);
}
Where 'this' is the Form itself which has all the references to the objects I need to manipulate?
It's probably worth noting that I've learned a good bit about the Cross-Thread calls and I've started making Extension methods for many instances that I need which are simplistic.
Another question - I notice that the Visual Designer automatically makes all Components created with it private by default, is it in general a bad idea to make these internal and use the form object to reference these components as needed from outside the class? If it is not a good idea, what is better?
First I would suggest to separate independent user-interface parts into UserControls or Components. Then - if needed - wire them using Events (eg. your own specialized events and properties.
For example you can place your main content (the TabControl / Container) in a UserControl and place that user control in the main form. All tab-/page-switching logic/UI etc. then belongs to that user control. In that UserControl you can define for example your own Event that gets fired when the user switches a tab. The main form then can register to this event - just like it can for other Winforms-control-events - and do its stuff (eg. change the window title to represent the currently active tab).
Then next you can move the content of each tab to its own user-control and use these user-controls within your new tabs-usercontrol. Move the logic down to the UserControl which is responsible for the given task.
A form/controls hierarchy from some typical application could look like this:
MainForm (Form)
MainTabContainerControl (UserControl)
Page1Control (UserControl)
Page2Control (UserControl)
MyImprovedDbRowGridControl (UserControl or Component)
Page3Control (UserControl)
SidebarControl (UserControl)
SearchControl (UserControl)
MyImprovedDbRowGridControl (UserControl or Component)
QuickHelpControl (UserControl)
Next thing is so keep all the UI-eventhandlers as small as possible and doing only UI stuff. Move other logic like business- or dataaccess-logic to other classes outside of the user-interface.
If you have combinations of the controls that are needed more then once in the application: move them to a re-usable UserControl. (eg. breadcrum).
Regarding your sample code you can make it more compact and therefore maintainable by simplyfing its logic:
if (this.fSelectedButton.Equals(this.RadioButton_Delete))
{
this.TextBox_DestinationFile.Enabled = false;
this.Button_DestinationBrowse.Enabled = false;
}
else
{
this.TextBox_DestinationFile.Enabled = true;
this.Button_DestinationBrowse.Enabled = true;
}
...could be:
var delete = fSelectedButton == RadioButton_Delete;
this.TextBox_DestinationFile.Enabled = !delete;
this.Button_DestinationBrowse.Enabled = !delete;
Update:
When it comes to refactoring and code-cleanup a very usefull tool is Resharper (R#). I can highly recommend it.
Hope this gives you some ideas where to start.

c# flickering Listview on update

I have a list view that is periodically updated (every 60 seconds). It was anoying to me that i would get a flicker every time it up dated. The method being used was to clear all the items and then recreate them. I decided to instead of clearing the items I would just write directly to the cell with the new text. Is this a better approach or does anyone have a better solution.
The ListView control has a flicker issue. The problem appears to be that the control's Update overload is improperly implemented such that it acts like a Refresh. An Update should cause the control to redraw only its invalid regions whereas a Refresh redraws the control’s entire client area. So if you were to change, say, the background color of one item in the list then only that particular item should need to be repainted. Unfortunately, the ListView control seems to be of a different opinion and wants to repaint its entire surface whenever you mess with a single item… even if the item is not currently being displayed. So, anyways, you can easily suppress the flicker by rolling your own as follows:
class ListViewNF : System.Windows.Forms.ListView
{
public ListViewNF()
{
//Activate double buffering
this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint, true);
//Enable the OnNotifyMessage event so we get a chance to filter out
// Windows messages before they get to the form's WndProc
this.SetStyle(ControlStyles.EnableNotifyMessage, true);
}
protected override void OnNotifyMessage(Message m)
{
//Filter out the WM_ERASEBKGND message
if(m.Msg != 0x14)
{
base.OnNotifyMessage(m);
}
}
}
From: Geekswithblogs.net
In addition to the other replies, many controls have a [Begin|End]Update() method that you can use to reduce flickering when editing the contents - for example:
listView.BeginUpdate();
try {
// listView.Items... (lots of editing)
} finally {
listView.EndUpdate();
}
Here is my quick fix for a C# implementation that does not require subclassing the list views etc.
Uses reflection to set the DoubleBuffered Property to true in the forms constructor.
lvMessages
.GetType()
.GetProperty("DoubleBuffered", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic)
.SetValue(lvMessages, true, null);
Update for 2021:
I got pinged on this old post with a comment and I would write this code differently now. Below is an extension method that will add a new method to a ListView to be able to set the double buffered property to true/false as required. This will then extend all list views and make it easier to call as reqired.
/// <summary>
/// Extension methods for List Views
/// </summary>
public static class ListViewExtensions
{
/// <summary>
/// Sets the double buffered property of a list view to the specified value
/// </summary>
/// <param name="listView">The List view</param>
/// <param name="doubleBuffered">Double Buffered or not</param>
public static void SetDoubleBuffered(this System.Windows.Forms.ListView listView, bool doubleBuffered = true)
{
listView
.GetType()
.GetProperty("DoubleBuffered", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic)
.SetValue(listView, doubleBuffered, null);
}
}
If this can help, the following component solved my ListView flickering issues with .NET 3.5
[ToolboxItem(true)]
[ToolboxBitmap(typeof(ListView))]
public class ListViewDoubleBuffered : ListView
{
public ListViewDoubleBuffered()
{
this.DoubleBuffered = true;
}
}
I use it in conjonction with .BeginUpdate() and .EndUpdate() methods where I do ListView.Items manipulation.
I don't understand why this property is a protected one...even in the .NET 4.5 (maybe a security issue)
Yes, make it double buffered. It will reduce the flicker ;) http://msdn.microsoft.com/en-us/library/system.windows.forms.listview.doublebuffered.aspx
Excellent question and Stormenent's answer was spot on. Here's a C++ port of his code for anyone else who might be tackling C++/CLI implementations.
#pragma once
#include "Windows.h" // For WM_ERASEBKGND
using namespace System;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;
public ref class FlickerFreeListView : public ListView
{
public:
FlickerFreeListView()
{
//Activate double buffering
SetStyle(ControlStyles::OptimizedDoubleBuffer | ControlStyles::AllPaintingInWmPaint, true);
//Enable the OnNotifyMessage event so we get a chance to filter out
// Windows messages before they get to the form's WndProc
SetStyle(ControlStyles::EnableNotifyMessage, true);
}
protected:
virtual void OnNotifyMessage(Message m) override
{
//Filter out the WM_ERASEBKGND message
if(m.Msg != WM_ERASEBKGND)
{
ListView::OnNotifyMessage(m);
}
}
};
You can use the following extension class to set the DoubleBuffered property to true:
using System.Reflection;
public static class ListViewExtensions
{
public static void SetDoubleBuffered(this ListView listView, bool value)
{
listView.GetType()
.GetProperty("DoubleBuffered", BindingFlags.Instance | BindingFlags.NonPublic)
.SetValue(listView, value);
}
}
The simplest Solution would probably be using
listView.Items.AddRange(listViewItems.ToArray());
instead of
foreach (ListViewItem listViewItem in listViewItems)
{
listView.Items.Add(listViewItem);
}
This works way better.
Simple solution
yourlistview.BeginUpdate()
//Do your update of adding and removing item from the list
yourlistview.EndUpdate()
I know this is an extremely old question and answer. However, this is the top result when searching for "C++/cli listview flicker" - despite the fact that this isn't even talking about C++. So here's the C++ version of this:
I put this in the header file for my main form, you can choose to put it elsewhere...
static void DoubleBuffer(Control^ control, bool enable) {
System::Reflection::PropertyInfo^ info = control->GetType()->
GetProperty("DoubleBuffered", System::Reflection::BindingFlags::Instance
| System::Reflection::BindingFlags::NonPublic);
info->SetValue(control, enable, nullptr);
}
If you happen to land here looking for a similar answer for managed C++, that works for me. :)
This worked best for me.
Since you are editing the cell directly, the best solution in your case would be to simply refresh/reload that particular cell/row instead of the entire table.
You could use the RedrawItems(...) method that basically repaints only the specified range of items/rows of the listview.
public void RedrawItems(int startIndex, int endIndex, bool invalidateOnly);
Reference
This totally got rid of the full listview flicker for me.
Only the relevant item/record flickers while getting updated.
Cheers!
Try setting the double buffered property in true.
Also you could use:
this.SuspendLayout();
//update control
this.ResumeLayout(False);
this.PerformLayout();
In Winrt Windows phone 8.1 you can set the following code to fix this issue.
<ListView.ItemContainerTransitions>
<TransitionCollection/>
</ListView.ItemContainerTransitions>
For what it's worth, in my case, I simply had to add a call to
Application.EnableVisualStyles()
before running the application, like this:
private static void Main()
{
Application.EnableVisualStyles();
Application.Run(new Form1());
}
Otherwise, double buffering is not enough. Maybe it was a very old project and new ones have that setting by default...
If someone would still look an answer for this, I used a timer for a slight delay and it solved the problem nicely. I wanted to highlight (change colour) for the entire row on mouse move event, but I think it would work for item replacement etc. For me listView.BeginUpdate() and listView.EndUpdate() didn't work, DoubleBuffered property also didn't work, I have googled a lot and nothing worked.
private int currentViewItemIndex;
private int lastViewItemIndex;
private void listView_MouseMove(object sender, MouseEventArgs e)
{
ListViewItem lvi = listView.GetItemAt(e.X, e.Y);
if (lvi != null && lastViewItemIndex == -1)
{
listView.Items[lvi.Index].BackColor = Color.Green;
lastViewItemIndex = lvi.Index;
}
if (lvi != null && lastViewItemIndex != -1)
{
currentViewItemIndex = lvi.Index;
listViewTimer.Start();
}
}
private void listViewTimer_Tick(object sender, EventArgs e)
{
listView.BeginUpdate();
listView.Items[lastViewItemIndex].BackColor = Colour.Transparent;
listView.Items[currentViewItemIndex].BackColor = Colour.Green;
listView.EndUpdate();
lastViewItemIndex = currentViewItemIndex;
listViewTimer.Stop();
}

How do I make a Windows Forms control readonly?

Returning to WinForms in VS2008 after a long time.. Tinkering with a OOD problem in VS2008 Express Edition.
I need some controls to be "display only" widgets. The user should not be able to change the value of these controls... the widgets are updated by a periodic update tick event. I vaguely remember there being a ReadOnly property that you could set to have this behavior... can't find it now.
The Enabled property set to false: grays out the control content. I want the control to look normal.
The Locked property set to false: seems to be protecting the user from accidentally distorting the control in the Visual Form Designer.
What am I missing?
For some typical winforms controls:
http://jquiz.wordpress.com/2007/05/29/c-winforms-readonly-controls/
This is also a good tip to preserve the appearance:
Color clr = textBox1.BackColor;
textBox1.ReadOnly = true;
textBox1.BackColor = clr;
To make the forms control Readonly instantly on one click do use the following peice of Code :
public void LockControlValues(System.Windows.Forms.Control Container)
{
try
{
foreach (Control ctrl in Container.Controls)
{
if (ctrl.GetType() == typeof(TextBox))
((TextBox)ctrl).ReadOnly = true;
if (ctrl.GetType() == typeof(ComboBox))
((ComboBox)ctrl).Enabled= false;
if (ctrl.GetType() == typeof(CheckBox))
((CheckBox)ctrl).Enabled = false;
if (ctrl.GetType() == typeof(DateTimePicker))
((DateTimePicker)ctrl).Enabled = false;
if (ctrl.Controls.Count > 0)
LockControlValues(ctrl);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
Then call it from your Button Click Event like this :
LockControlValues(this)
Hope, this helps to solve your problem :
Happy Programming,
Rajan Arora
www.simplyrajan.co.nr
Textbox
.ReadOnly property to true
Controls without ReadOnly
Other control do not have all the time the ReadOnly property. You will require to play with the Events to take off the editing process and keeping your value not editable.
Two relevant properties ReadOnly and Enabled. ReadOnly = true prevents editing grays out the background, but it still allows focus. Enabled = false grays out the background, text and prevents editing or focus.
Windows UI conventions dicate giving the user a visual cue that a control is readonly (that way they won't attempt to edit it and be subsequently frustrated). The grayed out disabled state is the defined system convention, but it's arguable too much of a cue (and not a legibile enough one).
The simplest route is probababy to set your control to ReadOnly, set the background to System.Drawing.SystemColors.Window and then block focus messages. You could do this by catching OnEnter events and immediately moving Focus to another control that's not readonly (say, a Close or Edit button). Or you could derive your own control and eat any WM_SETFOCUS messages. Example below.
I believe various third-party control sets give you additional options and granularity.
public class ReadOnlyTextBox : TextBox
{
const uint WM_SETFOCUS = 0x0007;
public ReadOnlyTextBox()
{
this.ReadOnly = true;
this.BackColor = System.Drawing.SystemColors.Window;
this.ForeColor = System.Drawing.SystemColors.WindowText;
}
protected override void WndProc(ref Message m)
{
// eat all setfocus messages, pass rest to base
if (m.Msg != WM_SETFOCUS)
base.WndProc(ref m);
}
}
I was given this same requirement at work yesterday. Except instead of a textbox I had to make an entire form disabled without changing it's color.
So I replaced a call to
form->Enabled = false;
with
IntPtr hWnd = form->Handle;
HWND window_handle = (HWND)hWnd.ToPointer();
::EnableWindow(window_handle, aEnable ? TRUE:FALSE);
Which worked well. You can see above that I am using managed C++. The entire form is now disabled, but not greyed out.

Categories

Resources