I have a small project here in visual studio 2022, a Winforms c /CLR project. It is a pretty simple project and form, but I have an issue with the following:
In the Winforms app I use a small panel to display the status of some input that I get. I want to change the background colour of the panel depending on the status of that variable. So for example if the variable is 0, the background colour should be red, if the value of the variable is 1, it should be green.
I can easily make this work, when this is coupled to a trigger event from the user, such as mouseclick, mousehover, .... But how do I make this work dynamically during runtime, such that even while the variable changes during runtime, the backgroundcolour of the panel changes with it too, without the need of a user input event such as a mouseclick, ... ?
What kind of class need to be made in order to make this work?
CodePudding user response:
I suggest you to use the TextChanged
event in the textbox
, which triggers when the content of the textbox
changes, you could refer to the following code:
private: System::Void textBox1_TextChanged(System::Object^ sender, System::EventArgs^ e) {
if (textBox1->Text != "")
{
if (textBox1->Text == "1")
button1->BackColor = Color::Red;
else if (textBox1->Text == "2")
{
button1->BackColor = Color::Green;
}
}
}
The result is as follows:
CodePudding user response:
An example that shows how to bind the Property of a Control to the Property of managed class object, implementing the INotifyPropertyChanged interface, used to trigger value change notifications.
In the ColorTrigger
class, when an the value of an int
Property is changed, this also changes the value returned by a Property of Type Color
and triggers a PropertyChanged notification.
This causes all Controls bound to the class object to read again the value of the Property specified in the binding:
somePanel->DataBindings->Add(
"BackColor", trigger, "ColorValue", false, DataSourceUpdateMode::OnPropertyChanged
);
Here, DataBindings.Add() binds to the BackColor
Property of a Panel Control to the ColorValue
Property of the ColorTrigger
class.
#pragma once
#include "ColorTrigger.h"
public ref class SomeForm : public System::Windows::Forms::Form
{
// Initialize with default values
private: ColorTrigger^ trigger = gcnew ColorTrigger();
public: SomeForm(void) {
InitializeComponent();
somePanel->DataBindings->Add("BackColor", trigger, "ColorValue", false, DataSourceUpdateMode::OnPropertyChanged);
}
Or pass different Colors to the Constructor of the ColorTrigger
class:
// [...]
private: ColorTrigger^ trigger;
public: SomeForm(void) {
InitializeComponent();
trigger = gcnew ColorTrigger(gcnew array<Color> {
Color::Magenta, Color::Cyan, Color::Orange
});
somePanel->DataBindings->Add("BackColor", trigger, "ColorValue", false, DataSourceUpdateMode::OnPropertyChanged);
}
Now, when you assign a new value to the Value
Property of the ColorTrigger
class, the Color returned by the ColorValue
Property changes accordingly and a notification is sent, causing the Binding to update and with it the Property of Controls that share the binding.
ColorTrigger
managed class:
Note that this line in the Property setter:
colorIdx = Math::Max(Math::Min(value, colors->Length - 1), 0);
trims the value
in the range (0, [ColorArray].Length - 1)
.
You may want to throw instead, if value
is outside the bounds of the array.
#pragma once
using namespace System;
using namespace System::ComponentModel;
using namespace System::Drawing;
#define nameof(_propname) #_propname
public ref class ColorTrigger : INotifyPropertyChanged
{
public:
virtual event PropertyChangedEventHandler^ PropertyChanged;
private:
array<Color>^ colors;
int colorIdx = 0;
public:
ColorTrigger(void) {
this->ColorTrigger::ColorTrigger(
gcnew array<Color> {Color::Green, Color::Orange, Color::Red}
);
}
ColorTrigger(array<Color>^ colorArr) {colors = colorArr;}
public :
property int Value {
int get() { return colorIdx; }
void set(int value) {
if (value != colorIdx) {
colorIdx = Math::Max(Math::Min(value, colors->Length - 1), 0);
ColorValue = colors[colorIdx];
}
}
}
property Color ColorValue {
Color get() { return colors[colorIdx]; }
private : void set(Color value) {
OnPropertyChanged(nameof(ColorValue));
}
}
void OnPropertyChanged(String^ prop) {
PropertyChanged(this, gcnew PropertyChangedEventArgs(prop));
}
};