How to persist custom user control property in application settings? - c#

I created simple user control consisting of 3 elements:
2 radio buttons and table layout panel aka Yes or No control.
I created custom property boolean "Value" which changes depending of checked radio button.
UPDATE 1: I added that control to form and bind property "Value" to settings and in control code I added logic to determine which radio but should be checked but after saving settings and reloading form neither of radio buttons are checked.
How can I achieve that effect with the least effort.
Below the code:
public partial class YesOrNoControl : UserControl
{
public YesOrNoControl()
{
InitializeComponent();
LoadValue();
}
[Description("Sets the value of Control"), Category("Behavior"), DefaultValue(false), Browsable(true)]
public bool Value { get; set; }
void LoadValue()
{
if (Value)
{
YesButton.Checked = true;
}
else
{
NoButton.Checked = true;
}
}
private void YesButton_Click(object sender, EventArgs e)
{
Value = true;
}
private void NoButton_Click(object sender, EventArgs e)
{
Value = false;
}
}

You can define application settings within the IDE (under project settings).
You can then manipulate the settings by use of the Properties.Settings namespace.
Settings are automatically loaded at runtime, you can save the settings by calling the Save() method.
More links: Using Application Settings and User Settings
Applications Settings for WinForms

I managed to solve my problem.
I modified property "Value" to get value from application setting (specially created for this purpose) and set value to same application setting.
At the end of setter I added saving of application settings.
It solves the main problem but it's kind of workaround, not the true answer to problem.
Below the modified code of property:
public bool Value
{
get
{
return Properties.Settings.Default.YesOrNoControlValue;
}
set
{
Properties.Settings.Default["YesOrNoControlValue"] = value;
Properties.Settings.Default.Save();
}
}

Related

how to Validate Picker in xamarin forms using Behavior?

using xamarin forms & PCL.
i want to validate the Picker using the Behavior to ensure that user picked an item from the Picker.
my behavior class is
public class PickerValidationBehaviour :Behavior<Picker>
{
private Picker _associatedObject;
public string PropertyName { get; set; }
protected override void OnAttachedTo(Picker bindable)
{
base.OnAttachedTo(bindable);
_associatedObject = bindable;
if (_associatedObject.SelectedIndex < 0 )
{
HandleValidation();
}
}
private void HandleValidation()
{
}
private void _associatedObject_SelectedIndexChanged(object sender, EventArgs e)
{
}
protected override void OnDetachingFrom(Picker bindable)
{
base.OnDetachingFrom(bindable);
_associatedObject = null;
}
}
}
and i was stuck because i want execute the validation before user action, such that the submit button will be hidden until the user fill the form.
and beside if there is any easy efficient way that i can perform the validation please mention it.
I think this scenario you should put logic in VM instead of using behavior.
Cause behavior can change some UI element, like color something and most of them are the element itself's property.
In your case, you want to change another element in Page. There is a problem, how to access another element in your page.
If you binding SelectedIndex in you VM, and when property changed you can raise another property which controls the submit button. That will be easier then do it in behavior.

DataBinding DataGrid to ObservableCollection<T> is creating 2 different instances of the DataGrid and only the default is shown

The data binding works as it I intend, kind of... The real issue I'm running into now is what I believe to be 2 different instances of my User Control, but only the original, debug list I implemented is showing.
In short, I am building 2 lists that are technically bound to the data grid, the default debugging list I created in the default constructor and then the real list I created to bind to the data grid.
Every time I click on the user control with the data grid, the default constructor adds another line to my debugging list and displays it on the screen.
Every time I click the button that builds a list of selected options on a separate user control I can see my the options add on to the list of options I had been creating and technically set it to the data context of the data grid, the same way the default debug list does, except when I click back over to the data grid user control, the default constructor runs again, ads another line to my debug list, and displays the debug list that is being built.
Here's a copy of the class with a couple lines I added to help debug the problem.
public partial class QuotePreview : UserControl
{
private SelectionList _selectionList;
private SelectionList temp;
public QuotePreview()
{
InitializeComponent();
_selectionList = (SelectionList)this.DataContext;
}
private void QuotePreview_Loaded(object sender, RoutedEventArgs e)
{
//Adds item to Debugging list
_selectionList.SelectedOptions.Add(
new Selection
{
ModelNumber = "this",
Description = "really",
Price = "sucks"
});
}
public QuotePreview(SelectionList selectedOptions)
{
InitializeComponent();
_selectionList = (SelectionList)this.DataContext;
temp = selectedOptions;
//The list I am actually trying to display
_selectionList.AddRange(selectedOptions);
QuotePreview_Loaded();
}
private void QuotePreview_Loaded()
{
foreach (var options in temp.SelectedOptions)
{
_selectionList.SelectedOptions.Add(options);
}
QuotePreviewDataGrid.ItemsSource = _selectionList.SelectedOptions;
}
}
The implementation of the default constructor, is called every time the user control / tab, is clicked on. When that happens, _selectionList is set to the data context of the user control, followed by the Loaded Event which adds a line to my data grid.
In another user control where I select the options I want to add to my data grid user control, I click a button that creates a list of the options I want to be added and calls the custom constructor I wrote. Once the constructor finishes, it calls a custom Loaded Event method that I created for shits and giggles, that adds the selected options to my _selectionList.
Now once I click on the data grid user control again, it goes through the whole default process, and adds another default line.
If I go back a tab and say I want these options again and go back to the data grid, it again goes through the default process and adds another default line.
Whats most intriguing though is that I can see both of the selectionLists build since I dont clear the in between processes. I see a list build of the options i want to display and a list build of the default options build...
Oh, also, SelectionList does implement ObservableCollection
i don't follow exactly what you are asking but loaded event will fire whenever load is required and in your case you are switching between the views , TabControl will not render its content until it is required !
bool _isDefaultItemAdded = false
private void QuotePreview_Loaded(object sender, RoutedEventArgs e)
{
if(!_isDefaultItemAdded)
{
//Adds item to Debugging list
_selectionList.SelectedOptions.Add(
new Selection
{
ModelNumber = "this",
Description = "really",
Price = "sucks"
});
_isDefaultItemAdded = true;
}
}
I finally came up with a solution to the problem.
public static class QuotePreview
{
public static ObservableCollection<PurchasableItem> LineItems { get; private set; }
static QuotePreview()
{
LineItems = new ObservableCollection<PurchasableItem>();
}
public static void Add(List<PurchasableItems> selections)
{
foreach (var selection in selections)
{
LineItems.Add(selection);
}
}
public static void Clear()
{
LineItems.Clear();
}
}
public class QuoteTab : TabItem
{
public ObservableCollection<PurchasableItem> PreviewItems { get; private set; }
public QuoteTab()
{
Initialize()
PreviewItems = QuotePreview.LineItems;
DataGrid.ItemSource = PreviewItems
}
}

How to persist design time property changes that were made programmatically?

I have a custom control that I added an Id string property to.
When the control is placed on a form, I want the constructor to set this to Guid.NewGuid().ToString(), but only if it hasn't been set before.
When I manually edit this property from the designer, it adds a line of code to the Designer.cs file. How can I do that programmatically?
Specifically, how to do it from within the custom control?
I have created sample usercontrol that fits your requrements. In this case is "MyLabel" that inherits from Label.
First create separate library that holds MyLabel class and here is the code for this class:
public class MyLabel: Label
{
public string ID { get; set; }
protected override void OnCreateControl()
{
base.OnCreateControl();
if (this.DesignMode && string.IsNullOrEmpty(this.ID))
{
this.ID = Guid.NewGuid().ToString();
}
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
this.Text = this.ID;
}
}
As you see my control has ID property that is populated if control is in design mode and no value has been set yet. Checking design mode is important so value will not change if you reopen the project.
Override for OnPaint event is there just to see actual ID value in real time it's not required.
I believe what you need is Properties.Settings. See MSDN page.
You can set these to default values during design, or load and save at runtime.
Example: with the designer, create a new user scoped string[] named IDs. Then in your constructor, something like this
string ID = "";
if (Properties.Settings.Default.IDs!=null && Properties.Settings.Default.IDs.Length>0) {
ID = Properties.Settings.Default.IDs[0];
}
else {
ID = "random";
Properties.Settings.Default.IDs = new string[1];
Properties.Settings.Default.IDs[0] = ID;
Properties.Settings.Default.Save();
}
This will use the first element of the stored array if there is one, or it will create a new string if there isn't, and persist it (so it will be read from the settings next time you run the program).

Setting default properties for toolbox items?

I don't want the button I add to have dotted borders when clicked, so I found out that I can disable that by turning off the focus cues. I don't want to have to change settings like this for each individual button I add. Is there any way to set property defaults in Visual Studio?
What you need to do is create a new Control based on Button and use it throughout your application.
public class MyButton : System.Windows.Forms.Button
{
protected override bool ShowFocusCues
{
get { return false; }
}
}

Passing User Control Class to Host Page

How can I pass user control properties to the page AND make these properties available to all methods on the page (and not just to one method that is fired on a control action, e.g. onControlClick)
I have a set up of essentially 3 pages:
user control (ascx/cs)
class (cs) - that contains user control properties
host page (aspx/cs) - references the user control
The user control consists of 3 interrelated dropdowns. I'm having success passing these dropdown values through a class onto the page via an event that is fired when a user clicks on the dropdown menu. So this way the host page is continously aware of the values in the user control. However, I want the page to use the control's properties (stored in a class) on all of its methods - how do I make this user control class available to all?
Also I'm using ASP.NET and C# by the way.
Here's the Code (not sharing the full code here - just the snippets of a similar code block)
On the ASPX for Menu Host Page:
<linked:LinkMenu2 id="Menu1" runat="server" OnLinkClicked="LinkClicked" />
Host Page (cs):
protected void dropdownclicked(object sender, ddtestEventArgs e)
{
if (e.Url == "Menu2Host.aspx?product=Furniture")
{
lblClick.Text = "This link is not allowed.";
e.Cancel = true;
}
else
{
// Allow the redirect, and don't make any changes to the URL.
}
}
Host Page (aspx)
<asp:dropdowncustom ID="dddone" runat="server" OnddAppClicked="dropdownclicked" />
Control (cs)
public partial class usercontrol_tests_dropdown1 : System.Web.UI.UserControl
{
public event ddtestEventHandler ddAppClicked;
}
public void selectapp_SelectedIndexChanged(object sender, EventArgs e)
{
ddtestEventArgs args = new ddtestEventArgs(selectlink.SelectedValue);
ddAppClicked(this, args);
}
Class:
public class ddtestEventArgs : EventArgs
{
// Link
private string link;
public string Link
{
get { return link; }
set { link = value; }
}
public ddtestEventArgs(string link)
{
Link = link;
}
}
public delegate void ddtestEventHandler(object sender, ddtestEventArgs e);
Hopefully this is what you're after. The best way to do it is to expose your controls as public properties from your user control. So, in your user control, for each drop down list add a property:
public DropDownList DropDown1
{
get { return dropDownList1; }
}
public DropDownList DropDown2
{
get { return dropDownList2; }
}
You can do the same for any other properties you want to access on the host page:
public string DropDown1SelectedValue
{
get { return dropDownList1.SelectedValue; }
set { dropDownList1.SelectedValue = value; }
}
Then, from your host page you can access the properties through the user control:
string value = UserControl1.DropDown1SelectedValue;
or
string value = UserControl1.DropDownList1.SelectedValue;
Here's a couple of other answered questions that you might find useful as I think (if I've understood correctly) this is what you're doing:
Getting data from child controls loaded programmatically
How to change the value of a control in a MasterPage.

Categories

Resources