combobox constant value - winforms

I have a form that has a combobox . I need this combobox value to remain unchanged even if the user closes and reopens the form. The value should remain constant, unless the user updates it, then the updated field will remain constant.

Then you need to store the selected value somewhere - depending on the lifetime you need to decide where.
If you are closing and opening the entire application then you will need to store the value in a database or file - an xml file may be your best bet.
If you only need to keep it unchanged for the lifetime of the application then you can store it in memory - lets say in a static variable of the form, the following demonstrates that option:
public partial class Form1 : Form
{
static string selection;
public Form1()
{
InitializeComponent();
comboBox1.SelectedItem = selection;
}
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
selection = (string)comboBox1.SelectedItem;
}
}

You need to set combo.SelectedValue to the right value on form Load
private void Form_Load(object o , EventArgs e)
{
combo.SelectedValue = someData.SomeID;
}
For full example : vb.net, combobox.datasource will change selected index?

Related

Winform Timer isn't running if statement when criteria is met

Hi I've come across either a weird bug or I'm not understanding something.
To cut a long story short I've had everything I'm wanting to work on my form working fine, I then decided to turn the form into an options menu so it was no longer the first form that appears when the application is launched and is shown after I click a button on a different form with the code
private void ShowOptionsButton_Click(object sender, EventArgs e)
{
formHomePage.Show();
}
And for some reason a timer if statement is no longer working:
private void StartSubCheckT_Tick(object sender, EventArgs e)
{
if (subliminalMessages.Count > 0)
{
MessageBox.Show("list greater than 0 if");
StartSubB.Enabled = true;
}
there are other if statements below but are irrelevant and the point of this is to make a button usable once a list is greater than 0. I've created another test button to display the value and it shows that the sublminalMessages list is greater than 0
private void testbutton3_Click(object sender, EventArgs e)
{
MessageBox.Show(subliminalMessages.Count.ToString());
}
Which outputs at 1 which it should be from some other code that adds a value in at the beginning. But for some reason even with the subliminalmessages.count being greater than 0 the if statement is no longer being called ever since I'm making the form appear being called from another form from the button code above.
The subliminalMessages list is being populated and created on the same form
public List<string> subliminalMessages = new List<string>();
private void Form1_Load(object sender, EventArgs e)
{
if (!String.IsNullOrEmpty(Settings.Default["Subliminal1"].ToString()))
{
subliminalMessages.Add(Settings.Default["Subliminal1"].ToString());
MessageBox.Show("If worked");
}
}
There is a value in the Setting.Default that is being added
The button and timer are on the same form and the timer in question is enabled.
Does anyone know why?
Thanks
I'll have a stab at giving you an answer. But it's a little swerve from what you're doing now.
From what I understand of your code you are using the timer to enable/disable the StartSubB button. Or maybe just enable it.
Instead of relying on the timer which appears to not work why not use a BindingList<string>. This has an event called ListChanged which you can handle and then enable/disable your button.
Here's a test form I created:
public partial class Form1 : Form
{
BindingList<string> items;
public Form1()
{
InitializeComponent();
button3.Enabled = false;
items = new BindingList<string>();
items.ListChanged += Items_ListChanged;
}
private void Items_ListChanged(object sender, ListChangedEventArgs e)
{
button3.Enabled = items.Count > 0;
}
private void btnAdd_Click(object sender, EventArgs e)
{
items.Add("a");
}
private void btnRemove_Click(object sender, EventArgs e)
{
if (items.Count > 0)
items.RemoveAt(items.Count - 1);
}
}
I have a BindingList<string> called items. This is analagous with your subliminalmessages list but it's a BindingList. This type of list has a ListChanged event that fires when items are added or removed from the list. In the constructor we new up the items list and subscribe to the ListChanged event.
When the Items_ListChanged event fires button3 is enabled or disabled based on whether items.Count > 0 or not.
In btnAdd_Click we just add an item to the list.
In btnRemove_Click we check that there are some items then remove the last one.
If you were to run this you'd see that when we click the Add button, button3 gets enabled. If we click the Remove button we'll see button3 get disabled.
The only limitation of BindingList is that you can't add a range by passing in another List.
If you implement this and your button still doesn't activate then you'll probably need to post some more code. Strip out all the irrelevant stuff and put it in a new project that demonstrates the failure of the condition and either copy the code here or provide a link to download the project. The only reason the if statement should fail is if the list is actually empty.

Get Clipboard value from static variable

So a sequel to my last post...
I have PieChart with Legend and i want to be able to right click on Legend title and copy the value.
So this is the Legend Mouse Right click Event:
private void pieLegend_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
{
var hoveredItem = this.pieLegend.Items.FirstOrDefault(x => x.IsHovered);
Clipboard.SetText(hoveredItem.Title);
}
As you can see i am copy the value the the Clipboard but i want to open simple Copy menu so i create ContextMenu and i have the ContextMenu Click Event:
private void MenuItem_Click(object sender, RoutedEventArgs e)
{
}
Not inside this Click Event i want to get the Clipboard but because pieLegend_MouseRightButtonDown event is fired before this Click Event i want to find a way to get this Clipboard value.
So i was thinking about create a Static variable that the first Event will set the Clipboard value and from the Click Event just get this value but my question is if this is the best way/appropriate way to do that.
Well, there's nothing wrong with doing both.
I think you are over thinking this, you really need to consider your requirements.
In this particular scenario, I would not suggest using the clipboard to transfer data from the two events. Why? Well, because the user can easily just copy something else onto their clipboard which may be completely unrelated to your application, therefore it could be erroneous.
So, I expect defining a private or static variable (This really depends on the scope, you don't need to define a static variable if you don't have to) is the correct way to go.
private string _HoveredItemTitle;
private void pieLegend_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
{
var hoveredItem = this.pieLegend.Items.FirstOrDefault(x => x.IsHovered);
Clipboard.SetText(hoveredItem.Title);
_HoveredItemTitle = hoveredItem.Title;
}
And in your other method, it'd be a good idea to check if there is something in this variable, otherwise it may not be a good idea to go a head with the execution.
private void MenuItem_Click(object sender, RoutedEventArgs e)
{
if (string.IsNullOrEmpty(_HoveredItemTitle))
{
//TODO: Something useful
return;
}
//TODO
}
I think the main idea I'm trying to get across here is that you should ensure that there is nothing (or as little as possible) that the user can do to cause errors in your application. In this scenario, copying the text to the clipboard is nice, but it's more of a feature than a requirement. The application should not have to rely on the clipboard, simply because there might be complete nonsense on the clipboard, instead of the data that you are actually expecting.

Winforms, Combobox, Databinding... allow user to type in a value not found in the DataSource

Just like the title says... I have a Winforms application with a databound dropdown. I want the user to have the convenience to pick from a bunch of predefined values, but also the ability to type in his own value
If I just enable databinding and set dropdown type to anything but DropDownList, it allows me to enter anything I want, but does not persist it to the objects...
Seems like a simple problem to solve... help?
I've added an event handler on ComboBox.Leave this code would add the newly typed in string in the combobox to the underlying list(countries) as well as refresh the combobox binding to it.
Limitations
You'd have to handle the addition of new element based on the type of datasource you have.
The List.Contains is case sensitive you might want to keep all the strings in one case. And convert the user entered value to that case before deciding to add it to the datasource.
Here you go, modify the comboBox1_Leave eventhandler according to your datatypes and datasource.
public partial class Form1 : Form
{
private List<string> countries;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
countries = new List<string>();
countries.Add("Australia");
countries.Add("Belgium");
countries.Add("Canada");
comboBox1.DataSource = countries;
}
private void comboBox1_Leave(object sender, EventArgs e)
{
ComboBox combo = (sender as ComboBox);
CurrencyManager cm = (combo.BindingContext[combo.DataSource] as CurrencyManager);
if (!cm.List.Contains(combo.Text))
{
cm.List.Add(combo.Text);
cm.EndCurrentEdit();
cm.Refresh();
cm.Position = cm.Count - 1;
}
}
}

Silverlight Required TextBox Attached Property

I have a need to create an attached property for a TextBox, that enforces a rule that content is required.
NOTE: Unfortunately I am not able to use data annotations, or SL4 validation frameworks.
The textboxes are displayed within the context of a View. The View is reused in many places. When tabbing / clicking between TextBoxes within the view I want a popup message to notify the user if they have left a 'Required' TextBox empty.
Now, I have this working via the LostFocus event:
public static readonly DependencyProperty RequiredProperty =
DependencyProperty.RegisterAttached("Required", typeof(bool), typeof(TextBoxRequiredService),
new PropertyMetadata(OnRequiredChanged));
public static bool GetRequired(DependencyObject d)
{
return (bool)d.GetValue(RequiredProperty);
}
public static void SetRequired(DependencyObject d, bool value)
{
d.SetValue(RequiredProperty, value);
}
private static void OnRequiredChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
TextBox textBox = d as TextBox;
textBox.LostFocus += (s, args) => {
if (textBox.Text.Length == 0) {
MessageBox.Show("Required Field!");
textBox.Focus();
}
};
}
But this is getting triggered, obvioulsy, on every lost focus, and there are certain situations, for example closing the view, that i don't want the validation to execute.
So, does anyone have any good suggestions (or examples) on a way to get a Required Text Box service working within a definable scope of actions? Or perhaps some clever alternatives to LostFocus that I could use?
Thanks,
Mark

Extending WPF Button to store data in a new property

I want to extend a WPF button to store some extra data, in a similar way to the current "Tag" property. Are attached properties the way forward? The data I want to store will be a URL Link string, for example I would like to be able to do something like:
<Button Tag="BBC World News" URLLink="http://www.bbc.co.uk"/>
Can anyone help me to understand how to extend the Button?
Many thanks
Jay
You can use an attached property:
public class ButtonBehavior
{
public static readonly DependencyProperty UrlLinkProperty =
DependencyProperty.RegisterAttached("UrlLink",
typeof(ButtonBase),
typeof(ButtonBehavior),
new FrameworkPropertyMetadata(null));
public static string GetUrlLink(DependencyObject d)
{
return (string)d.GetValue(UrlLinkProperty);
}
public static void SetUrlLink(DependencyObject d, string value)
{
d.SetValue(UrlLinkProperty, value);
}
}
Then you can declare your button like this:
<Button Tag="BBC World News" ButtonBehavior.UrlLink="http://www.bbc.co.uk" Click="btnArticleView"/>
And you click handler will look like this:
protected void btnArticleView(object sender, RoutedEventArgs e)
{
Button rb = sender as Button;
string TheTitle = rb.Tag.ToString();
string TheURL = ButtonBehavior.GetUrlLink(rb);
// Further code here
}
Define the attached property like this
public static readonly DependencyProperty UrlLinkProperty =
DependencyProperty.RegisterAttached("UrlLink",
typeof(String),
typeof(ButtonBehavior)
new FrameworkPropertyMetadata(null));
I am not sure about your goal here. You dont need to extend the Button for storing two values. You can always set the Datacontext of the Button with custom data object which contains this two values. Can you explain more on your problem.
Thanks for your response.
I have a listbox which has a complex custom data template. The template contains a button. When I click the button I want to send 2 strings which are "URL link" and "URL Title". So I am binding many values in my list box data template, and I want to pass two of them on Button click event. Code example:
protected void btnArticleView(object sender, RoutedEventArgs e)
{
Button rb = sender as Button;
string TheTitle = rb.Tag.ToString();
string TheURL = rb.URLLink.ToString();
// Further code here
}
and XAML:
<Button Tag="BBC World News" URLLink="http://www.bbc.co.uk" Click="btnArticleView"/>
Cheers
Jay
I know this is an old post but...
you could always create a custom class "MyURL" with 2 properties "URLText" and "URLTitle" then create that object "objURL" and set the values and set the button.datacontext = objURL.
Then in the click event difine rb and obj and your text variables
obj = rb.datacontext
theTitle = obj.urltitle
theURL = obj.urltext

Resources