WPF, share methods between two UserControl classes - c#

I have two UserControl classes, RequiredFields and OptionalFields. I wanted to have a base class, Fields, that would inherit from UserControl and contain methods that both RequiredFields and OptionalFields would use. However, when I try to do that, I get the following error:
Partial declarations of 'MyNamespace.OptionalFields' must not specify different base classes
Here are my class definitions:
public partial class OptionalFields : Fields
public partial class RequiredFields : Fields
public abstract class Fields : UserControl
Even if I make Fields a partial class instead of abstract, or if I make it a regular non-abstract non-partial class, I get the same error.
Is what I'm wanting to do possible/reasonable? If not, what is the best way of sharing methods between UserControl instances?

Do you have an OptionalFields.xaml? If so, it is automatically generating OptionalFields.g.cs which contains the C# code that the XAML represents. It contains a class that inherits from UserControl (or whatever the XAML's root element is).
Try changing the root element in the XAML file to Fields.

Do you need to updated the other side of the partial? I.e. is OptionalFields.Designer.cs inheriting from UserControl still?
Edit: sorry being too winforms, I of course mean OptionalFields.xaml

Related

Design view of Form class that inherits from BaseForm<T> [duplicate]

I am trying to clean up all designer errors in our solutions and ran into the following error:
The designer could not be shown for this file because none of the classes within it can be designed. The designer inspected the following classes in the file: DoubleAttributeTextBoxBase --- The base class 'NumericAttributeTextBoxBase' could not be loaded. Ensure the assembly has been referenced and that all projects have been built.
The classes are both defined in the same assembly so I know it's not a reference problem. I'm wondering if it has anything to do with the fact that the base class is generic. Any ideas?
public class DoubleAttributeTextBoxBase : NumericAttributeTextBoxBase<double>
public class NumericAttributeTextBoxBase<T> : TextBox where T : IComparable, IComparable<T>
The base class for a class being designed must be non-abstract and non-generic. To make a class that inherits from a generic class designable. The workaround is to insert a trivial non-generic class in-between:
public partial class DoubleAttributeTextBoxBase
: NumericAttributeTextBoxBaseOfDouble
{
public DoubleAttributeTextBoxBase()
{
InitializeComponent();
}
// Now DoubleAttributeTextBoxBase is designable.
}
public class NumericAttributeTextBoxBaseOfDouble
: NumericAttributeTextBoxBase<double>
{
}
To make this as simple as possible, you can even put the non-generic class in the same file as the class you want to design. Just make sure to put it after the class (as I have done above) because the designer expects the first class in the file to be the one being designed.
I don't know of a solution, this has been a severe limitation of Visual studio since C# 2.0 came out. The only thing I can say is to add that control to the page at runtime, then at least you can have your designer back for everything else.
from msdn:
Your component or control cannot be a generic type, which is also called a template type or a parameterized type. The design environment does not support generic types.
http://msdn.microsoft.com/en-us/library/ms171843.aspx

Winforms: best approach to deal with 'unsupported generic base class' in designer [duplicate]

I created a generic base class for a WinForm UserControl:
public partial class BaseUserControl<T> : UserControl
{
public virtual void MyMethod<T>()
{
// some base stuff here
}
}
And a UserControl based on that:
public partial class MyControl : BaseUserControl<SomeClass>
{
public override void MyMethod<SomeClass>()
{
// some specific stuff here
base.MyMethod<SomeClass>();
}
}
It works fine, but MyControl cannot be edited in the VisualStudio Designer, because it says it cannot load the base class.
I tried to define another class BaseUserControl, non generic, hoping it would load it, but the trick doesn't seem to work.
I already have a workaround: define an interface, IMyInterface<T>, and then create my control as
public partial class MyControl : UserControl, IMyInterface<SomeClass>
But I lose my base virtual methods (not a big deal, but still...).
Is there a way to create a base generic class for a UserControl, with the possiblity to edit it in the VisualStudio Designer?
We're doing the same thing and we work around by specializing a class first and derive from the specialized class.
Using the code from your example this means something like:
public partial class UserControl : UserControlDesignable
{
...
}
public class UserControlDesignable : BaseUserControl<Someclass> { }
The designer is still acting flaky sometimes - but most of the time it works.
You'll have to trick the designer by adding a 'regular' class that inherits from your generic base form.
Your designable form should then inherit from this class.
The following 2 class definitions are thus in the same file. You'll have to make sure that the class that inherits from the generic base user-control, is the last class in the file.
public MyForm : EditableCustomerForm
{}
public EditableCustomerForm : GenericForm<Customer>
{}
The designer will display the first class in the code file that it encounters.
Well this appears to be a bug in Visual studio.
By digging into the framework (actually by adding a RootDesignerSerializer with a custom type derived from CodeDomSerializer and overriding the serialize method), I was able to prove that the VS Code Dom provider is actually parsing wrong the generic classes, and instead of considering it as a generic class it is considering it as a regular class with the name class<T>, which Type.GetType() can of course not find.
I am still searching for a way to work around it, but in the mean time one can use the solutions above.
There is a Microsoft.Connect bug report on it, please vote on it at https://connect.microsoft.com/VisualStudio/feedback/details/797279/win-forms-designer-error-when-inheriting-from-a-generic-form

View with a baseclass in WP7 and MVVMLight

I'm having multiple views in my project and want them to derive from a base class where some navigation logic is handled. This logic doesn't belong in the VM, so I've got it placed in the View.
Now when I'm trying to change the base class of the view I'm receiving the following error:
Partial declarations of
'ProjectName.Results' must not specify
different base classes.
The only thing I've changed is:
public partial class Results : PhoneApplicationPage
to:
public partial class Results : BaseView
I can't find any other decleration of the Results class in my project. Perhaps MVVMLight generates something while building.
Is it possible to let the views derive from a base class? It should be, but I can't get it to work.
Assuming that your BaseView inherits PhoneApplicationPage like following:
public class BaseView : PhoneApplicationPage
{
//...
}
After changing from:
public partial class Results : PhoneApplicationPage
To:
public partial class Results : BaseView
Also change your XAML from something like:
<phone:PhoneApplicationPage x:Class="WindowsPhonePivotApplication1.Results"
To:
<local:BaseView x:Class="WindowsPhonePivotApplication1.Results"
also add a xml namespace like following:
xmlns:local="clr-namespace:WindowsPhonePivotApplication1"
Your Results class declaration is met in XAML as well as in code-behind file what's why you got this error. Yes It's possible to inherit views classes from base one but I think you'd better use composition to embed your navigation logic, for instance you may create a custom control for it and insert it in all your views.

Generic base class for WinForm UserControl

I created a generic base class for a WinForm UserControl:
public partial class BaseUserControl<T> : UserControl
{
public virtual void MyMethod<T>()
{
// some base stuff here
}
}
And a UserControl based on that:
public partial class MyControl : BaseUserControl<SomeClass>
{
public override void MyMethod<SomeClass>()
{
// some specific stuff here
base.MyMethod<SomeClass>();
}
}
It works fine, but MyControl cannot be edited in the VisualStudio Designer, because it says it cannot load the base class.
I tried to define another class BaseUserControl, non generic, hoping it would load it, but the trick doesn't seem to work.
I already have a workaround: define an interface, IMyInterface<T>, and then create my control as
public partial class MyControl : UserControl, IMyInterface<SomeClass>
But I lose my base virtual methods (not a big deal, but still...).
Is there a way to create a base generic class for a UserControl, with the possiblity to edit it in the VisualStudio Designer?
We're doing the same thing and we work around by specializing a class first and derive from the specialized class.
Using the code from your example this means something like:
public partial class UserControl : UserControlDesignable
{
...
}
public class UserControlDesignable : BaseUserControl<Someclass> { }
The designer is still acting flaky sometimes - but most of the time it works.
You'll have to trick the designer by adding a 'regular' class that inherits from your generic base form.
Your designable form should then inherit from this class.
The following 2 class definitions are thus in the same file. You'll have to make sure that the class that inherits from the generic base user-control, is the last class in the file.
public MyForm : EditableCustomerForm
{}
public EditableCustomerForm : GenericForm<Customer>
{}
The designer will display the first class in the code file that it encounters.
Well this appears to be a bug in Visual studio.
By digging into the framework (actually by adding a RootDesignerSerializer with a custom type derived from CodeDomSerializer and overriding the serialize method), I was able to prove that the VS Code Dom provider is actually parsing wrong the generic classes, and instead of considering it as a generic class it is considering it as a regular class with the name class<T>, which Type.GetType() can of course not find.
I am still searching for a way to work around it, but in the mean time one can use the solutions above.
There is a Microsoft.Connect bug report on it, please vote on it at https://connect.microsoft.com/VisualStudio/feedback/details/797279/win-forms-designer-error-when-inheriting-from-a-generic-form

C# Apply Interface to a Form Class

How can I apply an Interface to a form class
partial class Form1 : Form, InterfaceA
Is this correct?
Basically I would like to implement an Interface on a form.
How To ....
A Form is just a class (that subclasses System.Windows.Forms.Form), so yes - standard syntax is fine, as you have it.
Edit: As to your partial class part of the question, no, you need only declare that you implement the interface once. From MSDN...
If any of the parts are declared abstract, then the entire type is considered abstract. If any of the parts are declared sealed, then the entire type is considered sealed. If any of the parts declare a base type, then the entire type inherits that class.
Remember, there's no magic in forms or partial classes. C#/.Net is one of the few Microsoft projects that's wizardry free - it really does tend to behave the way you think it should.
Yes - a form is just a class at the end of the day
When working with partial classes in C#, either:
any declaration with the ':' operator must specify exactly the same baseclass and interfaces
specifying baseclass and interfaces on one of the declarations will suffice
To make life easier for yourself, add the interface specs in only one place (without checking I suspect this is in the designer class part by default when working with the WinForms designer).

Categories