Does Visual Inheritance work with User controls in VS2008 - winforms

I have a base User Control. I place Ok and Cancel buttons on the bottom right of the control and anchor them Bottom and Right.
I then create another user control that inherits from the base user control. I resize the inherited control (e.g. increase height or width). Throw the inherited control onto the form. Run. The inherited control does not honor the anchor properties of the Ok and Cancel buttons.
Here are the exact steps to repro.
1 - Create a new winforms project
2 - Create a base control (BaseControl1) with a Ok and Cancel buttons located at bottom/right. Anchor them there at Bottom,Right. Compile the app.
3 - Create a new User Control (UserControl1) that inherits from the base control (BaseControl1), created in step 1.
4 - Increase (in the designer) UserControl1's height or width.
5 - Throw UserControl1 onto Form1. Run. You'll see that Ok and Cancel buttons are not where they are supposed to be.
Am I doing something wrong, or does VS2008 simply not honor the anchor properties of the controls on the base user control?

Change the Modifiers property on your buttons to Protected. Then, after you complete step 4, you'll notice the designer code for UserControl1 now contains a line of code to set the buttons' locations. That wasn't happening when your buttons were scoped as Friend.
I've always wondered why controls dropped from the toolbox weren't scoped to Private by default.

I think your problem is that the default values for the Anchor property is not to be anchored. When you change the property and compile, that doesn't mean that's the default setting for classes that inherit your control.
If you are using the property selector, Visual Studio automatically puts some code in your application to change those values (i.e the designer code). Find the InitializeComponent() method and I bet you'll see something to the effect of:
this.myOKButton.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
this.myCancelButton.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
You'll need to set this property somewhere in your class, like the constructor, or override that property and specify the way you want it anchored.

Related

All control's properties disabled in Visual Studio

I have a parent form and a child form that inherits from the former. In design mode all the inherited controls' properties are disabled. How can I change these properties in the child form?
Here is a screenshot of the designer. Note how I have selected a text box and all its properties are disabled (greyed out).
By default, the Windows Forms designer creates components with the private access modifier. This means that an inheriting form will render the controls, but cannot modify them.
To fix this, open the base form in the designer. Select the control(s) that you want to be able to modify and change the Modifiers property to Protected.
Important: After this change, you must rebuild the base form's project for changes to show up in the inheriting form's designer view.

Winforms Databinding and multiple Forms

i have a main window that contains multiple UserControls, arranged as tab pages and tab groups (much like Visual Studio allows to have two or more editors visible at the same time).
I also have the possibility to open such an UserControl into a seperate floating window.
One of these UserControls contains simple form fields (e.g. text boxes). These text boxes are bounded with common databinding to an object / property. The binding mode is OnValidation (not on OnPropertyChanged).
When I switch the focus from this User Control inside the main window into another UserControl in the Main windows, the validation is automatically performed and the databinding is finised / the changed text will be set on the model object / property that is bounded to that text field.
But if I switch the focus to an UserControl which resides in another (floating) window, the databinding is not finished since no validation is performed.
I know that I can handle this manually by triggering ValidateChildren etc, but this seems to my the wrong way / is ugly.
Is there a "correct" / clean way to solve this issue? I want that the validation is performed as soon as the UserControl loses its focus or the window gets deactivated.
One information: On of my UserControls contains a TreeControl. If I edit a tree node label, and when I switch the focus to another (foating) window, the label edit is finished automatically. I want the corresponding behaviour for usual form fields regarding binding...
Thanks for help!
There is no automatic way to do this. From the point of view of the control, it still has the focus (if you click the title bar or Alt-tab back to the main window, you will notice that the focus remains in the same control). Its just that the form the control is on is not active. If you want it to save changes when your form is deactivated, you must manually trigger it. The best way to do that is probably to override the OnDeactivate method of the form.
protected override void OnDeactivate(EventArgs e)
{
base.OnDeactivate(e);
this.ValidateChildren();
}

Custom Control Appearance

I created my own user controls that inherit from the standard .net controls (for example MyTextBox : TextBox). MyTextBox has within it some custom logic, and also sets some style properties (eg colour). I build the project that contains these controls, and they get added to my toolbox. I then drag them onto the windows form designer. The problem is that when I drag them, the windows form designer automatically includes the style definition for the control that i dragged. For example
this.myTextBox1.BackColor = System.Drawing.Color.Gray;
Now, if later on during development I decide to change the colour for all instance of MyTextBox in the solution from Gray to White, I cannot simply go to the MyTextBox control code, change it there and rebuild. The change will not be applied to existing text boxes, since this property will be overridden in the forms designer! What is the best approach to handle such cases?
you can control the designer code generation with an attribute ... http://msdn.microsoft.com/en-us/library/system.componentmodel.designerserializationvisibilityattribute.aspx

How to dynamic add/remove control with Expression Blend?

A while I go, I made a demo application with Expression Blend.
My first screen is a big selections of Buttons, so when user click on any of button, it goes to the MainView.
Then in the MainView, I have a list of Menu items that user can click and shows up its corresponing DisplayView. (Appointment Menu Item will shows up AppointmentView etc).
Everything is good, I can click the MenuItem, the Views shows up with animation and transition effects.
But the thing is, with creating in Expression Blend, the MainView, Menu, AppointmentView etc every thing is predefined in the XAML. So when user load the first screen has to load everything into memory.
Now thinking of it, shouldn't the MainView etc be dynamically add into the screen?
How do I do it with Expression Blend? Or the only way to do is just....do it in code-behind myself (writting StoryBoard etc for the dynamic add/remove controls?)
If there is any example/tutorial of doing it, it will be great.
I guess you have very limited possibilities to conditionally load or unload controls exclusively in Blend without writing code-behind.
In general an opening tag in XAML is equivalent to a parameter-less constructor of some class object. As soon as you write the tags your are instantiating an object but that doesn't mean that it's visual appearance is loaded into memory. This only happens when the control is actually shown on the screen.
In my opinion the leanest way to control the appearance of some control is to use a single-child control. Take a Border control for example and add the user control you want to conditionally load to its child property, so you can decide for example whether to load or unload a control.
But unfortunately I think you have to do this in code as well. Take this easy code snippet:
// either instantiate in code or use from markuup
Border myBorder = new Border();
// the control you want to conditionally appear and disappear
UserControl myUserControl = new UserControl();
myBorder.Child.Add(myUserControl);
Of course a much more sophisticated approach is to use Grids. Here you have to use attached properties to add or remove child elements:
// either instantiate in code or use from markuup
Grid myGrid = new Grid();
// the control you want to conditionally appear and disappear
UserControl myUserControl = new UserControl();
// set the target position inside the Grid via the Grids attached properties
Grid.setRow(myUserControl, 1);
Grid.setColumn(myUserControl, 0);
// actually add the control
Grid.Children.Add(myUserControl);
Although I am pretty sure you were aware of all of that I am hoping it helped a bit :)

Custom Wizard Control in WPF to add and remove UserControls?

How best can I create a Wizard control in WPF. My tak is; first I have a Wizard Controller UserControl, that contains two buttons, i.e. Back and Next, then I have start off with two other UserControls with forms for users to fill in and click next step to the next form etc... What I woud like to know is how I could inserted this usercontrols and validate my current object before going to the next form. What can I use to get the next and previous events or is there a better solution for this?
Im still learning WPF, and am working on WinForm project atm, so sorry for any WinForm references in this.
The wizard control could contain a reference to each usercontrol the wizard will display. The wizard will add all these controls to itsself controls.add(_userControl1). Each control has its visible property set to false.
The wizard could also contain a private enum with a list of control names, i.e.
private enum CurrentControl
{
_MyControl1,
_MyControl2,
_MyControl3
}
Wizard control keeps a reference to the current displayed control CurrentControl _currentControl = CurrentControl._MyControl1; Have a UpdateDisplay() method, which based on the _currentControl will only make that one control visible.
Then when you click on Prev/next buttons, it updates the _currentControl varible based on its current value, calls UpdateDisplay() to show th enext control.
This way you have a reference to all your user controls (and thus the data they contain), and thus you can validate the content and your wizard can go back and forward through them by using the buttons on the wizard, and the logic in the wizard showing and hiding the controls.
You might be interested in the EmailClient (ViewModel) sample application of the WPF Application Framework (WAF). It shows how to create a Wizard with the Model-View-ViewModel pattern and it contains validation logic which disables the Next button when the user input is not valid.

Resources