View with a baseclass in WP7 and MVVMLight - c#

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.

Related

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

Using "partial" on a generic class

I am using a generic class called ViewModelCollection<BaseViewModel> which handles a lists of ViewModels and delivers standard add() and delete() commands.
Now I'm wondering if I can "extend" this class using the partial construct for a certain ViewModel, whose name is, say, CarViewModel.
Is something like this possible?
partial class ViewModelCollection<BaseViewModel>
{
... some command and list stuff ...
}
partial class ViewModelCollection<CarViewModel>
{
... special commands for car view model
}
No, you can't, partial just splits the class definition over multiple files, the definition has to be the same. You need to derive from ViewModelCollection<T>:
public class ViewModelCollection<T> where T: BaseViewModel
{
//methods
}
public class CarViewModelCollection : ViewModelCollection<CarVieModel>
{
//specific methods
}
partial is used only to split a class across multiple source files. The class definition itself must be the same.
Take the partial methods added and create an interface, you can then constrain the generic to use that interface and work off of those methods defined.

WPF, share methods between two UserControl classes

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

Create a strongly typed view which inherites a class which is concrete

I am having one class called BaseClass which contains some logic applicable to whole web site.
In order to create a strongly typed view we need to inherit the page from System.Web.Mvc.ViewPage generic class. But In our case I have to Inherit the BaseClass from
System.Web.Mvc.ViewPage to apply some common settings, but the BaseClass should be inherited from System.Web.Mvc.ViewPage<> generic version. But I cannot inherit the BaseClass from System.Web.Mvc.ViewPage<> as it will change other class also. So I created one more class of type BaseClass<> inheriting it from System.Web.Mvc.ViewPage<> and copied the whole code of BaseClass in BaseClass<>. But the code in BaseClass is controlled by other team so it will be changed frequently so my BaseClass<> should be in sync with BaseClass. Please help me in eliminating the code duplication or any other approach to make strongly typed View.
Thanks
Ashwani
Ok... it seems like you can't change the use of this BaseClass for your views.
How about duplicating the logic of ViewPage<TModel>? Have a look at the ViewPage`1.cs file that is in the asp.net mvc source code and duplicate that. That would be the easiest way...
E.g.
public class BaseClass : ViewPage
{
//Custom logic for africa here
}
public class BaseClass<TModel> : BaseClass
{
//Copy and paste all the code from ViewPage`1.cs
//It's not much - about 50 lines.
}
HTHs,
Charles
Ps. The link to the source code is for asp.net mvc 2
Ouch...
I am not sure what you are having in your BaseClass. But I think the best option is to create a BaseViewModel (maybe your BaseClass is you BaseViewModel> and then create specific ViewModels (which inherits from BaseViewModel) for each page.
For example your ViewModels should look something like this:
public abstract class BaseViewModel
{
public string SiteTitle {get;set;}
public int SomeProperty{get;set;}
}
public class UserViewModel: BaseViewModel
{
public string UserName{get;set;}
public string Email{get;set;}
}
and you should create strongly typed view like this:
System.Web.Mvc.ViewPage<UserViewModel>
You can take a look at AutoMapper to simplyfy the mapping process from your custom classes to ViewModels.
Cheers
public abstract class MyBaseView<T> : ViewPage<T>
{
//common logic here
}
public class UserView: MyBaseView<MyUserInfo>
{}

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

Categories