I am trying to work with Modern UI, namely Modern Tab control.
I have created a LinkList of Pages(UserControls) and is popuating my tabcontrol with these, since I will be fetching data from a database, and thus it is not possible for me to know how many links the user will be presented with.
My problem is, binding an event to the Link, and loading content according to the selected Link.
I have tried to use SelectedSourceChanged="{Binding SelectedKalenderChanged}", but this is not possible.
I have then tried to call the event behind-code, however the event only fires off once, and I get no updates when the user selects another link.
Here is the method behind-code;
private void KalenderController_OnSelectedSourceChanged(object sender, SourceEventArgs e)
There is no e.Handled possibility.
Anyone have a suggestion on how I can raise a propertychanged event when the user selects another link?
Thank you in advance for any help/suggestions
I found out what i was doing wrong, i was naming my page uri on list creation with the same name.
By doing this;
public MainViewModel()
{
LinkList = new LinkCollection();
KalenderList = new ObservableCollection<Kalender>();
KalenderList = DataHandler.HentKalendere();
foreach (var kalender in KalenderList)
{
LinkList.Add(new Link
{
DisplayName = kalender.Navn,
Source = new Uri("/Pages/UgePage.xaml#"+kalender.Navn, UriKind.Relative)
});
}
_selectedKalender = LinkList[0].Source;
}
i am now able to detect which link was selected.
Related
I am using 2 way binding with winforms text boxes.
I need to work out if the user has changed my data
Looking at the help for
the CurrentItemChanged Event
It seems that this event does fire if a property has changed, however it also fires if current has changed.
Is there a way to tell whether the data has changed?
a similar question is also asked here
but not answered in my opinion
Oliver mentions "if your object within the List support the INotifyPropertyChanged event and you replace the List by a BindingList you can subscribe to the ListChanged event of the BindingList to get informed about any changes made by the user."
My application meets these conditions but I cant get this working. The ListChangedType.ItemChanged property looked hopeful, but it changes when I navigate to the next record without changing the data
I found a link at Microsoft here but surely it cant be that hard!
This seems to work
void bindingSource_BindingComplete(object sender, BindingCompleteEventArgs e)
{
if (e.BindingCompleteContext == BindingCompleteContext.DataSourceUpdate)
{
var person = (Person)bindingSource.Current;
if ( person.State == State.Unchanged && (e.BindingCompleteState == BindingCompleteState.Success)
&& e.Binding.Control.Focused)
{
person.State = State.Modified; // using Julie Lerman's repositories technique
}
}
}
What is the best way to create and read multiple textboxes in a windows form? In my application, I have a windows form where customer can enter multiple addresses, email addresses
Right now I have a form like this,
TextBoxAddress1 TextBoxEmail1
TextBoxAddress2 TextBoxEmail2
.....
.....
.....
TextBoxAddressN TextBoxEmailN
For this I dragged and dropped multiple controls on a form and named each one of them.
If I use this method I had to write lengthy code to see if first row (TextBoxAddress1 TextBoxEmail1) is filled for validation and even for reading I had to write many lines of code.
Is there a better to way achieve this?
You can use the following code to add a TextBox dynamically to your form:
private int m_CurrTexboxYPos = 10;
private List<TextBox> m_TextBoxList = new List<TextBox>();
private void CreateCheckBox()
{
m_CurrTexboxYPos += 25;
TextBox textbox = new TextBox();
textbox.Location = new System.Drawing.Point(0, m_CurrTexboxYPos);
textbox.Size = new System.Drawing.Size(100,20);
Controls.Add(textbox);
m_TextBoxList.Add(textbox);
}
I would have a listbox/listview with your emails and Add/Edit/Delete buttons which show a popup form - the logic for validating emails, etc. would then be in the one place and your list can grow without you ever needing to add controls to the form.
You could dynamically create textboxes - but you end up writing code to make sure they layout nicely on the form, etc. - having some type of list is easier IMO and also lends itself to binding (e.g. to an email object)
Dynamically adding controls is pretty simple, provided you can use DockStyle and an exclusive container for them (e.g. a Panel). If you can't use DockStyle, then you need to write logic to determine Location and Size (which isn't fun).
On a simple form, I have two buttons and a panel, Button1 adds a new TextBox to Panel1, Button2 iterates through the controls in Panel1 and then checks that they are the correct type or throws an exception. This is where you you would put validation or reading logic. Panel1 needs to have AutoScroll = true; otherwise you will run controls off of the viewable screen.
This concept can be switched for anything that inherits from UserControl (all .Net native controls or your own custom controls).
private void button1_Click(object sender, EventArgs e)
{
TextBox NewEmailBox = new TextBox();
NewEmailBox.Name = "NewEmailBox" + this.panel1.Controls.Count;
NewEmailBox.Dock = DockStyle.Top;
this.panel1.Controls.Add(NewEmailBox);
}
private void button2_Click(object sender, EventArgs e)
{
foreach (Control item in this.panel1.Controls)
{
if (item is TextBox)
{
//Do your reading/validating here.
}
else
{
throw new InvalidCastException(string.Format("{0} was in Panel1 and is of type {1} not TextBox!", item.Name, item.GetType()));
}
}
}
Write a user control for each of the groupings you need. at least one One for address, one for email etc. then all of your validation, calls to your database access is contained in a single location
That is just good design. this way if you have multiple tabs for things like Home Information, Work Information, Emergency Contact Information, you can just place them on the form. This is pretty common for a user profile.
Then a listview for each grouping on a user profile page or whatever, that has edit/delete/add then popup a dialog with the appropriate user control in it.
Most simply, ListBox adove TextBox with Button.
Also you can use DataGridView, BuiltIn functionality for Add\Edit\Delete.
Here using DataGridView (ShowHeader set to false, EditMode to On Enter, with one Column with AutoSizeMode in Fill property)
The less of repeatable code you have, the better programmer you are.
Whenever you see a pattern (something what is repeatable), you could and you should try to optimize it. Unless it's something too small to worry.
In your case, determine first what is the basic of repeatable thing. Do you always have to enter address and email address? Then combine them into a control, which can carry out validation. Do you have to use this control often (or repeat N times)? Then maybe it make sense to switch to a list instead (ListBox, ListView or DataGridView).
Are you too lazy to bother configuring things? Then just optimize something what is obviously going to repeat: put validation into common method and call it from each TextBox event. Or make own TextBox with method build-in. Or do validation at once in the Ok button event by using loop.. or not by using loop.
To find best method you have to first decide best for who. Because customer want something shiny,easy to use, animated, with cats and boobs.. ok, without cats and boobs. The point is: how much work are you willing to put to have it best for the customer.
If I would have to enter table data (or data which form table), I'd go with DataGridView so it would looks like this.. or better:
I have a web form where I register a new employee. There're 3 parts in the form: Personal info, Address info, Special Status. But there's only one button for the whole form. When I submit the form all the information is updated to the database. So three Update statements are executed against the database. The methods are UpdatePersonalInfo, UpdateAddressInfo and UpdateSpStatus. Is there a way to check if there's been a change in any field in the certain part and run update method only if it's true. So something like this:
if (There's been any change to the personal data of the employee)
{
UpdatePersonalInfo;
}
if (There's been any change to the address information of the employee)
{
UpdateAddressInfo;
}
Sure I know, I can save all the previous values in a session object in PageLoad and then compare them one by one before running the method. But I thought maybe there's a magic way of doing this more easily.
Not sure that this is a better solution than any of the alternatives you already mentioned, but you could create a default handler to attach to the TextChanged, SelectedIndexChanged, etc events of your controls to keep track of which ones have changed.
List ChangedControls = new List(Of, String);
private void ChangedValue(object sender, System.EventArgs e) {
WebControl cntrl = (WebControl) sender;
ChangedControls.Add(cntrl.ID);
}
Then on your button click scour the ChangedControls list for the relevant controls.
I understand the "why" controls vanish on postback, and up until now I have had great success just creating what I need to do dynamically in page init. However this fell apart for me when I had to add some controls to a asp.net page based on the value of an existing dropdownlist.
So my question is simple, and I don't seem to be able to find a good working code example. I need to add some controls to the page based on the value of a dropdownlist. Then persist these added controls across other postbacks (session is fine).
Here is a snippet to work off of:
protected void Page_Init(System.Object sender, System.EventArgs e)
{
RebuildPlaceholder();
}
protected void ddlGroup_Change(System.Object sender, System.EventArgs e)
{
ExampleDataContext ctxExample = new ExampleDataContext();
var aryExample = (from rslt in ctxExample.mvExample
where rslt.label.ToLower() == ddlGroup.SelectedValue
select rslt);
foreach (var objExample in aryExample)
{
TextBox txtCreated = new TextBox();
txtCreated.ID = "ddl" + objExample.ID;
plcExample.Controls.Add(txtCreated);
}
StorePlaceholder();
}
private void StorePlaceholder()
{
//Need code to store all controls in a placeholder.
}
private void RebuildPlaceholder()
{
//Need code to rebuild all of the controls from Session.
}
I found this related article: Dynamically Adding Controls but I am struggling with the syntax for serializing all the controls, etc.
This can be limited to the child controls of a single placeholder that already exists on a page, just storing/restoring that placeholder's controls is what I am after.
Any version of ASP.NET is fine, if there is something that made this easy in 4.0 great.
Instead try caching the dropdown list selection. Then during the next page load use the cache to set the value selected. Then load the new controls based on that selection.
Session["CacheKey"] = DropDownList1.SelectedValue;
Then to access the Session Cache:
var value = Session["CacheKey"];
Take a look at this Microsoft article
on ASP.NET Caching
I've found that DropDownList.SelectedValue is unavailable during Page.Init. But you can still get access to the value with Request[ddl.UniqueID] and then create and add all your dynamic controls.
It feels kind of like a hack, but the ASP.NET page lifecycle doesn't allow many alternatives, particularly if your controls are not serializable.
I am working in a C# winforms project and I have a user control which gets loaded upon its selection from a tool-strip menu. I have a dictionary lookup set to occur upon form load of the user control for other functionality. Also, when I close the user control I am just using the ".Hide();" method. I noticed that when I load the user control the first time everything is fine, but when I close it and choose to open it again the 2nd time it creates a new instance of the object thus throwing off my dictionary lookup. Therefore, I wrote some code in an attempt to fix the issue.
What I need to do is to somehow say that if an instance of the user control already exists, do not create a new instance of that object. Instead, just make the user control visible again. Therefore I have written code in an attempt to accomplish this purpose. When I select the item the first time, everything is fine. When I hide the user control and try to re-open it again nothing happens.
The following is the code I have written for this purpose which occurs upon the selection of the item from the tool-strip menu:
if (Controls.ContainsKey("CheckAvailUserControl"))
{
Controls["CheckAvailUserControl"].Dock = DockStyle.Fill;
Controls["CheckAvailUserControl"].Visible = true;
Controls["CheckAvailUserControl"].Show();
Controls["CheckAvailUserControl"].Refresh();
}
else
{
UserControl checkAvailUserControlLoad = new CheckAvailUserControl();
Controls.Add(checkAvailUserControlLoad);
checkAvailUserControlLoad.Dock = DockStyle.Fill;
checkAvailUserControlLoad.Visible = true;
checkAvailUserControlLoad.Show();
}
When I trace through my code in the debugger it is in fact hitting the right parts of the above if/else statement. Its just not displaying the user control on the screen the 2nd time I attempt to load it.
The question is: How do I get the user control to load correctly after I close it, then select it from the tool-strip menu again?
I think that Controls.ContainsKey(...) is always returning false, because you never assigned a name to your control when you created it.
If, when you create the control, you say
//...
checkAvailUserControlLoad.Name = "Something"
//...
Controls.Add(checkAvailUserControlLoad);
then
Controls.ContainsKey("Something")
will return true, and you'll be able to re-use the control by using Controls["Something"]
Here you go:
private void button_Click(object sender, EventArgs e)
{
// pass in the containing panel
LoadControl<MyControls.MyControl>(panelContainer);
}
void LoadControl<T>(Panel panel) where T : Control, new()
{
T _Control = GetControl<T>(panel);
if (_Control == null)
{
_Control = new T();
_Control.Dock = DockStyle.Fill;
panel.Controls.Add(_Control);
}
_Control.BringToFront();
}
T GetControl<T>(Panel panel) where T : Control
{
Type _Type = typeof(T);
String _Name = _Type.ToString();
if (!panel.Controls.ContainsKey(_Name))
return null;
T _Control = panel.Controls[_Name] as T;
return _Control;
}
This could work, but I think it's a little bit backwards: you're throwing new code at a problem that could be solved instead by moving your old code.
Instead, think about how the events work in your form. I bet that if you move your creating code to a slightly different event, or detect when the event is fired later and ignore those, you could fix the problem in a much nicer way.