How to set default values for a user control? - c#

I got a user control called PicturePanel. On the mouse events (MouseDown, MouseMove, MouseUp), I have the following:
protected override void OnMouseDown(MouseEventArgs e)
{
if (marquee == true && e.Button == MouseButtons.Left && BackgroundImage != null)
{
//Code to create rectangular marquee
}
else
{
}
}
Class level variable private bool marquee = false by default. And a public one.
private bool marquee = false;
public bool Marquee
{
get { return marquee; }
set { marquee = value; }
}
I even tried assigning the false at initialization:
public PicturePanel()
{
InitializeComponent();
marquee = false;
}
But marquee is always true by default. If I want to turn off marquee, I have to set it through the public variable picturePanel1.Marquee = false in the form. How can I make marquee false by default within the user control?

I'm not sure if this is what you're talking about, but if you're referring to the default value that you see in the designer, then you just need to add the following attribute to your property:
[DefaultValue(false)]
public bool Marquee
...

Well, booleans are always false by default. You don't happen to have a local variable called marquee or something?
Just set a breakpoint on private bool marquee = false; and step through your code and you'll find it pretty quick.

Your issue might be that when you use the designer to "draw" the control on the form, it might be registering the MouseDown event, setting the Marquee to true. You can prevent this by checking this.DesignMode in your event handler.
Example:
if (this.DesignMode) return;

Related

How to create a FadeTo() animation based on BindableProperty change, MVVM style?

Let's say I have a view, with an <Image> element in it, that is visible based on whether it has a non-null property or not in the viewmodel. Like this:
<Image IsVisible="{Binding HasPhoto}" Source="{Binding Url}" />
With this ViewModel (only copied the relevant part):
private string url {get;set;}
public string Url {
get => url;
set {
url = value;
OnPropertyChanged(nameof(HasPhoto));
OnPropertyChanged();
}
}
public bool HasPhoto { get => Url != null; }
And somewhere in the ViewModel, I set: Url = null. This will cause HasPhoto to become false, and immediately render the <Image> element invisible, leaving no room to animate with .FadeTo(0) in the behavior. This is my current behavior implementation:
public class FadingBehavior : Behavior<VisualElement>
{
public uint FadeTime { get; set; } = 250;
protected override void OnAttachedTo(VisualElement bindable)
{
base.OnAttachedTo(bindable);
bindable.PropertyChanged += VisibilityMightHaveChanged;
}
protected override void OnDetachingFrom(VisualElement bindable)
{
base.OnDetachingFrom(bindable);
bindable.PropertyChanged -= VisibilityMightHaveChanged;
}
private void VisibilityMightHaveChanged(object sender, PropertyChangedEventArgs args)
{
var element = sender as VisualElement;
if (args.PropertyName == VisualElement.IsVisibleProperty.PropertyName)
{
var fadeToValue = element.IsVisible ? 1 : 0;
element.Opacity = -fadeToValue + 1;
element.FadeTo(fadeToValue, FadeTime);
}
}
}
This is fine, when the the <Image> becomes visible, because first it becomes visible, then it fades from 0 opacity to 1. But, for fading out this is not good, as the Url is removed instantly, rendering the image empty and invisible, so the fade-out animation cannot even start.
What is a good way to create an animation based on a bindable property value change?
I think that you are not far from a good solution.
What I would do is to inherit from Image and create FadableImage with bindable property called something like VisibilityHelper. Then when you assign the value to it the Image will still be visible and you can initiate the animation in a way that you already do. Just in the end when animation completes you should check the value of VisibilityHelper and if it is still the same also set IsVisible to the appropriate value.

C#: Create a Custom Control textbox which triggers events

I'm making a custom control textbox that has a Cue (filler text) and CueColor (filler text color) properties. I created an Enter and Leave event inside the textbox to regulate the Cue. When I tried applying it, however, it crashes my IDE (Visual Studio 2015, if this helps).
I've read a few posts with similar questions:
Winforms user controls custom events
Although I'm not quite sure if my problem has the same solution. How do I make it work? Here is my code for clarity:
class CueTextBox : TextBox
{
public string Cue
{
get { return Cue; }
set { Cue = value;}
}
public Color CueColor
{
get { return CueColor; }
set { CueColor = value; }
}
private void CueTextBox_Enter(object sender, EventArgs e)
{
TextBox t = sender as TextBox;
if (t.ForeColor == this.CueColor)
{
t.Text = "";
t.ForeColor = this.ForeColor;
}
}
private void CueTextBox_Leave(object sender, EventArgs e)
{
TextBox t = sender as TextBox;
if (t.Text.Trim().Length == 0)
{
t.Text = Cue;
t.ForeColor = this.CueColor;
}
}
}
The only thing that I see in your code is that the property definitions are recursively calling themselves and this will cause a stack overflow when adding the control to the design surface.
public string Cue
{
get { return Cue; }
set { Cue = value;}
}
Either define a backing field or use auto-implemented properties.
private string cue = String.Empty;
public string Cue
{
get { return cue; }
set { cue = value; }
}
or
public string Cue { get; set; }
Your question implied adding event handlers caused the issue. This can be a problem for custom controls at times. There is the Control.DesignMode property that is meant to allow conditional execution of code. However, it does not operate in the constructor. You need to do a bit of a hack to determine if the IDE is active.
This property can be used for development in Visual Studio as an alternative to DesignMode.
private bool InDesignMode
{
get
{
return (System.ComponentModel.LicenseManager.UsageMode == System.ComponentModel.LicenseUsageMode.Designtime) ||
base.DesignMode ||
(System.Diagnostics.Process.GetCurrentProcess().ProcessName == "devenv");
}
}
In solution development of custom controls is an exercise in self abuse. You are better of to go to Project Properties->Debug Tab and set the "Start Action" to "Start External Program" with "devenv.exe" as the program. This will start a new instance of VS when you "run" the debugger. When you add a control to the design surface of the new VS instance, you can debug your control's code. Break points will be hit and exceptions displayed.

How to enable a button to when one of my textbox changed in C#?

Today I got a problem in my development.
I have a Windows Form like this :
I need to enable the button "Appliquer" when the content of one of my textbox change.
I know that I can put the KeyPress event on each textbox and enable my button with that. In this window it can be easy to do that because there is only 10 textbox but I have an other window with more of 100 textbox and I think there is a better solution.
I tried to put the Keydown event directly in my windows form but it doesn't work.
So my question is, how can I do this. If someone have an idea ?
Thank you in advance !
Thomas
Since you already have 100+ textboxes in your form. I am assuming performance is not an issue for you.
In your form constructor, call this method. It will attach the event to all the textbox controls present in your form & inside sub controls such as groupbox, panel etc. (if you require)
There could be better ways of iteration..
public Form1()//your constructor
{
InitializeComponent();
AttachEvent(this);
}
void AttachEvent(Control CTrl)
{
foreach (Control c in CTrl.Controls)
{
if (c is TextBox)
{
c.TextChanged += new EventHandler(c_TextChanged);
continue;
}
if (c.HasChildren)
{
AttachEvent(c);
}
}
}
void c_TextChanged(object sender, EventArgs e)
{
//Your Code here btnGo.Enabled = !btnGo.Enabled;
}
What you can do is to extend TextBox make a field ( accessible from the designer ) to bind that TextBox into some other control.
public class MeTextBox
: TextBox
{
public override string Text
{
get { return base.Text; }
set
{
if ( m_DependantControl != null )
{
m_DependantControl.Enabled = !string.IsNullOrWhiteSpace(value);
}
base.Text = value;
}
}
Control m_DependantControl;
[Browsable(true)]
public Control DependantControl
{
get { return m_DependantControl; }
set { m_DependantControl = value; }
}
}
Now you can use MeTextBox as a regular TextBox. And if you want to make it control Enabled flag of some other Control you can just specify DependantControl property which will be accessible in the designer.
Fitting this into your example (code):
// assume you have a Button named btnConfirm
// and want to enable this button only when your `TextBox` has some text
MeTextBox mtb = new MeTextBox();
mtb.DependantControl = btnConfirm;
And if you do not want to make it in the code you can use designer directly.
To make it other way around ( one button dependant on many text boxes ) you can extend Button object :
public class MeButton
: Button
{
List<TextBox> m_DependantOn = new List<Control>();
[Browsable(true)]
public List<TextBox> DependantOn
{
get { return m_DependantOn; }
set { RemoveEvents(); m_DependantOn = value; AssignEvents(); }
}
void RemoveEvents()
{
foreach(TextBox ctrl in m_DependantOn)
ctrl.TextChanged -= WhenTextChanged;
}
void AssignEvents()
{
foreach(TextBox.ctrl in m_DependantOn)
ctrl.TextChanged += WhenTextChanged;
}
void WhenTextChanged(object sender, TextChangedEventArgs e)
{
this.Enabled = true;
}
}

Linklabel dotted focus area not appear when got focus with hotkey

I have LinkLabel. If i press hotkey, linklable got focus, but dotted area are not appear!
When it got focus by 'Tab', he have dotted focus area:
Next, if press hotkey, dotted area always appear.
How do I get the dotted area immediately appeared with the help of hotkeys?
I found the problem. All the matter in the protected property ShowFocusCues. It is set to the false by default. When you focus control by the "Tab", ShowFocusCues set to the true.
It is an example how to set ShowFocusCues to true:
public class UGLinkLabel : LinkLabel
{
private bool _displayFocusCues = true;
protected override bool ShowFocusCues
{
get
{
return _displayFocusCues;
}
}
public bool DisplayFocusCues
{
get
{
return _displayFocusCues;
}
set
{
_displayFocusCues = value;
}
}
}

Howto Add Custom Control Property in property Dialog Box

I want to add property's to my custom control like above example property with descriptions!
I don't know hot to display that with GUI like above.
I want to know what attribute to use it.
private bool IsNum = true;
[PropertyTab("IsNumaric")]
[Browsable(true)]
[Description("TextBox only valid for numbers only"), Category("EmSoft")]
public bool IsNumaricTextBox
{
set
{
IsNum = value;
}
}
protected override void OnKeyPress(KeyPressEventArgs e)
{
base.OnKeyPress(e);
if (IsNum)
{
doStruf(e);
}
}
private void doStruf(KeyPressEventArgs e)
{
if (!System.Text.RegularExpressions.Regex.IsMatch(e.KeyChar.ToString(), "\\d+") && !char.IsControl(e.KeyChar))
e.Handled = true;
}
I want to display this as property tool box with Description
Like This in property box
IsNumaric True
The property requires a Getter in order to be displayed in the property grid:
private bool isNum = true;
[PropertyTab("IsNumaric")]
[Browsable(true)]
[Description("TextBox only valid for numbers only"), Category("EmSoft")]
public bool IsNumaricTextBox {
get { return isNum; }
set { isNum = value; }
}
It is quite easy to achieve, you just have to decorate it with an attribute like in the sample below:
[PropertyTab("IsNumaric")]
[DisplayName("NumericOrNot")]
[Category("NewCategory")]
public bool IsNumaricTextBox
{
set
{
IsNum = value;
}
}
and to make it work you need following using:
using System.ComponentModel
If you do not specify Category - property will show under Misc category (please note, that by default properties are being shown by names, not by categories). In this example the property is going to be shown under NewCategory and the name of the property is going to be NumericOrNot.

Categories

Resources