Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I am making an application where the user has to choose a value from a combobox. Based on the users choice the form should be filled with relevant labels and textboxes. How do I achieve this?
One way I think this could be achieved is by creating all labels and textboxes, and based on the users choice hide the irrelevant ones. But this seems to be very cumbersome. Is there any neat way to do it?
Could you just give me leads from where I could pick up the many
ways? #Jumpei – user2276910 8 mins ago
Just you know, everything in the comments was a lead of some kind. Whichever approach you chose, showing/hiding data is essential. Your combobox selection is a private case. Much more frequently, you gonna need/use this to handle user access so there is no way you gonna start building your application and at some point discover that you can't show/hide data or controls. That's just not the case. In fact since each approach will give you that option, to get a concrete answer will require a lot more information about the project itself and the overall architecture than just this one particular form.
Having said that I will suggest you approach which I think is not the best one, but very intuitive and at some point when you feel more confident you change this.
So in order to achieve this create the form setting the default visibility to all elements. Adding/removing controls dynamically is not that trivial but setting the visibility option is pretty straight forward so I think it's better to start by using the visibility option.
When you are ready with the default state of the form you gonna need few methods. First, an event handler for the combobox select which should be something like this:
private void ComboBox1_SelectedIndexChanged(object sender, System.EventArgs e)
{
ComboBox comboBox = (ComboBox) sender;
string userSelection = (string)ComboBox1.SelectedItem;
From now on you should make a few things. First check if the userSelection is something valid. This check is essential, after you are sure that this is valid selection you gonna proceed (and we are still in the SelectedIndexChanged event) by calling a a method :
private void SetControlsToDefault()
{
}
This method will contains all your controls with their default visibility status. That's required because when the user make more than one selection with the combobox if we don't hide the once that were shown on the previous selection you will end up with visible controls when they should be hidden for the certain selection.
So once we are sure that the form is returned to it's initial state we need to check what exactly has the user selected and show the relevant controls.
Here some would suggest to use switch I'll suggest if-else if statements since I think this will make it more understandable but you can change it if you like so again in the event handler after calling SetControlsToDefault(); we have this:
if (userSelection.Equals("selection1"))
{
ShowControlsForSelectionOne();
}
else if (userSelection.Equals("selection2"))
{
ShowControlsForSelectionTwo();
}
else if (userSelection.Equals("selection3"))
{
ShowControlsForSelectionThree();
}
where ShowControlsForSelectionOne(), ShowControlsForSelectionTwo(), ShowControlsForSelectionThree() are all private methods where you gonna set the visibility only to those elements relevant to the selection. And that should be all. This is one of the many ways to complete this task.
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
I am creating a custom button control for a WPF application. The Button contains a ViewBox which in turn contains a TextBlock like this;
<Button>
<Viewbox>
<TextBlock Name="TextHolder"/>
</Viewbox>
</Button>
I want outside classes in C# to be able to access and change the text directly via a Property, like so;
public string Text
{
get { return TextHolder.Text; }
set
{
TextHolder.Text = value;
}
}
I am wondering if this is consider bad practice or not?
Thanks.
This piece of code of yours allows the part of the code that is responsible for "business logic" to look like:
this.Text = "mom";
instead of for example:
this.TextHolder.Text = "mom";
Difference is in accessing/exposing the TextHolder UI component. You don't want to expose them. That should be just a details of the 'presentation style'. Ideally the code should not care how the visuals look like (well, unless you are actually writing the code for the visual component like 'TextBlock'). What if you change your UI and TextHolder is no longer there and now you have a different presentation of the text, and it for example doesn't have control.Text but rather control.Data or control.Content? If TextHolder were exposed, you'd have to correct the code everywhere. With your piece of code, that "everywhere" uses your property this.Text, and TextHolder is hidden, so when it's gone, you just change the Text property getter/setter. This is a great thing.
And that's why, if anyone told you anything negative about this, would be wrong. Everything is better than scatterring accesses to UI component all over your business logic code. If you wanted to address that problem and came up with such a solution - great!
That being said, it's not the best you could have, and this is where the praise ends.
First of all you said you are using WPF. In WPF you there's a mechanism called data bindings. If you never used it, let me just say it's .. powerful. Unwieldy at times, but powerful. If you learned to and used data bindings, you would still have the Text property, but your code would not have TextHolder at all, not even in the getter/setter of .Text
Going further, once you learn at least the basics of data bindings, you can take it further and look at MVVM pattern. This one has the power of annihilating .xaml.cs and moving everything to view-agnostic "view models" - plain C# classes that have Properties and that never touch UI directly. WPF has mechanisms to observe them for any changes in their properties and then automatically refreshing the UI. It works two way - clicking/writing to a control may refresh properties in the "view model".
But there's a cost. It's all fine and dandy, but requires you to write some a bit repetitive boilerplace code and keep some defined patterns (though tools like i.e. PostSharp can do it for you, or frameworks like Caliburn.Micro can greatly simplify data binding expressions in XAML..).
I have a listbox in a winforms application that I would like to give a selection behavior that is different than the built in options for the control.If I choose multi-extended, I get what we are accustomed to - ability to use shift or control to select multiple items in the list. The multi-simple option lets you select individually and leave the item selected until you delect it. I'm trying to deal with a slightly different problem that could be solved by a combination of the two options. My users want to be able to use the shift key to highligh a long list and they don't want to accidentally lose their selection if they mistakenly click on one other item in the list. My thought was to keep everything hightlighted until they click a clear button. I kind of think they are asking for something that is not what Windows is meant to do and should not be allowed to do but I thought would post the question so see if anyone has done this before.
I'm looking for the best, most effecient way of implimenting user controls navigation based on events, below is the intended use.
I also don't know what is best, to have the next back button on the control or form.
Lastly, the next button may sometimes change and initially be validate on some controls and then if validated change to next if the validate is ok.
Ok the concept:
I have 1 primary user control with 3 checkboxes, behind each checkbox is a sequence of more user forms therefore, if all three are selected it should then load all three sequences one after another.
Regardless of how many are selected, all sequences end with the same final user control.
Basically I need to understand the best and most practicle way approach this (examples welcome).
There are lots of topics that cover winforms / user control navigation but I cannot seem to see a solution which pops out to me and fits my needs.
For compatibility with some systems, I have decided to use .net 3.5; should this make a difference in suggestions.
Feedback, links, code etc all welcome :)
I ran into a similar scenario some years ago. If memory serves, I approached it as follows:
Separate the navigation buttons into their own control that groups
the buttons together. Design this control to support docking.
In this control, provide distinct buttons for Back, Next, Finish and
Cancel. Provide separate properties on the control that determine
what the user can do: CanMoveBack, CanMoveForward, CanFinish, and
CanCancel. The container should be able to set these.
In the setter for the navigation properties, you want to be able to
adjust the visibility/disabled status of each of the navigation
buttons. Don't hot-swap text. That way, each button does one thing,
and only one thing. This keeps their event handlers nice and clean.
The user control itself should raise events: OnBackClicked,
OnNextClicked, OnFinishClicked, and OnCancelClicked. Your button
event handlers should raise these. The container should decide what
to do when they are clicked.
So , I'm trying to create a login form using windows forms and I have the username/password fields and another one where you can select a value from combobox. I want to add a new field is a specific value is selected from combobox. How can I do that?
Constructing forms on the fly is rather bad, especially when you know all the fields you will require upfront anyway. It results in a lot of code that deals with creating the UI, which is hard to read and to maintain. A good approach to solve this is putting all the fields you may need in a panel and hide this panel. When the right combobox item is selected, simply show the panel.
private void cbxOptions_SelectedIndexChanged(object sender, EventArgs e)
{
pnlFurtherOptions.Visible = (cbxOptions.SelectedIndex == 1);
}
If you need different panels for different combobox selections, you can realise that by putting the panels in a FlowLayoutPanel and only show the ones you need. Doing it this way, you can use the Designer to construct the forms (and have all the UI code where it should be). Furthermore, you can maintain the UI in the Designer as well.
I have a Windows form (.NET 3.5) that contains a propertygrid control. The propertygrid control gets refreshed periodically do display any changes that may have occurred in the class which it represents. I want the refresh to only occur if the user is not currently editing a property in the grid. Is there a way to detect if the user is currently editing a control?
Yes - it's a little hacky but you can find out which subcontrol of the property grid is active, and make an educated guess based on what it is. The following seems to work:
bool isEditing = (propertyGrid.ActiveControl.GetType().Name != "PropertyGridView");
There probably is, but might I recommend having your type implement INotifyPropertyChanged instead of refreshing the grid on a timer? This way you would never have to call Refresh yourself; the display would automatically update the value displayed for each property whenever that property changed.
Of course, if your type has tons of properties, or if you're using your grid to dynamically display objects of many different types, this suggestion may not be practical. It's just a thought.
This is a fairly complex problem. I'd suggest a two fold approach:
Keep track of the last time the changed events fire.
Keep track of whether or not the control has focus.
If the control hasn't been modified within a certain threshold and has focus, or if the control doesn't have focus, I'd consider that to be sufficient to determine that it is not currently being edited.
You could hook up the OnLostFocus event. This way, the control would only get updated once it no longer had focus.
protected virtual void OnLostFocus( EventArgs e)