Windows Phone 7 - Access MainPage UI control from Class - c#

I need to access control of MainPage.xaml.cs from another class. How can I access it?

The question is why? There are a couple of approaches, depending on your architecture:
First thing you can do is to make your MainPage singleton. It makes sense because you only have one Main Page in reality too, but I don't like singletons, and it makes your components coupled and your design becomes hard to unit test.
Alternatively, you can pass an interface of your MainPage into your class. If you only pass the interface, you then have the chance to do unit testing without too much trouble. Something like this:
public interface IMainView
{
void MethodOnMainPage();
}
public class MainPage : IMainView
{
}
public class MyClass
{
private IMainView _view;
public MyClass(IMainView view)
{
_view = view;
}
private void SomeEventHappened()
{
_view.MethodOnMainPage();
}
}

Related

How to architecture an app where many functionality classes want to have access to same class?

I need an architectural advice.
I have two classes:
public class Shell
{
public IPage CurrentPage { get; set; }
public void ChangePage(IPage page)
{
CurrentPage = page;
}
}
public class SomeFunctionallityClass
{
private readonly Shell _shell;
private readonly IPage _somePage;
public Model1(Shell shell, IPage page)
{
_shell = shell;
_somePage = page;
}
public void MakeSomeCrazyStuff()
{
_shell.ChangePage(_somePage);
}
}
In Shell class i have a CurrentPage property and this is the property which very many classes in the application want to have access to.
Right now i pass Shell object to the classes which need to change the page.
But what will be the best way to give access to the same class for many other classes?
Actually your solution of passing the Shell class to each other class that requires it, is not too bad, especially if you do it via the constructor.
Sure, the most common ways to do this are using the Singleton or a class with static methods. But if you are honest, in this context both of them are nothing but masked global state.
The original purpose of the singleton is to make sure only one object of a class exists, not to make something easily accessible. However the latter is the most common reason why developers use it. Other people therefore call it the "King of Antipatterns" :)
To be honest, I use both the Singleton and static methods myself in some cases to make my life easier (in the short term). But I never feel good about it.
To summarize, as far as I know you have three basic options:
Pass object in constructor
Singleton
Static methods
All of these have their pros and cons, but I consider the first solution the cleanest because it does not introduce global state.
You might want consider using Singleton design pattern:
https://msdn.microsoft.com/en-us/library/ff650316.aspx
Choose the one that fully answers your requirements.
You can make your Shell static:
public static class Shell
{
private static IPage CurrentPage { get; set; }
public static void SetCurrentPage(IPage page)
{
CurrentPage = page;
}
}
public class SomeOtherClass
{
public vod ShowShellPropery()
{
MessageBox.Show(Shell.Property);
}
}
Also having a setter ChangePage, you should make your CurrentPage private. Otherwise, you have two ways of changing your current page: with the setter ChangePage(page), and with CurrentPage = page, which is not good. Also I renamed your setter ChangePage to SetCurrentPage, so now it is clear that it is a setter

Decoupling ViewModels in MVVM

I know that in MVVM pattern (or possibly in any design pattern of this kind) we should keep our layers decoupled. From my understanding it also means, that I should keep my ViewModels separate. I'm having a bit trouble following this rule.
Say - I have a ConversationViewModel and a MessageViewModel - the former needs to create instances of the later. When ConversationViewModel gets notification about incoming message it spawns a new MessageViewModel instance and fills it with data.
The question is - if I create new MessageViewModel instances explicitly in the ConversationViewModel won't it make my app a bit harder to test? I mean - one unit of code is the ConversationViewModel and other is the MessageViewModel - I'd like to test both separate, so when somebody breaks something in the later, test for the former won't be affected. How do I achieve it?
I'm using MVVMLight, so I thought I would register MessageViewModel as an implementation of some interface, and then create a class like MockMessageViewModel implementing the same interface, but used only in tests. Then in the ConversationViewModel I'd ask the IOC container to just give me the registered implementation. Is it a good approach, or am I overreacting? Example code:
public class ViewModelLocator {
public ViewModelLocator() {
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
if (//in test) {
SimpleIoc.Default.Register<IMessageViewModel, MockMessageViewModel>();
}
else {
SimpleIoc.Default.Register<IMessageViewModel, MessageViewModel>();
}
}
public class ConversationViewModel : ViewModelBase {
public void MessageReceived(string data) {
//I'm thinking about doing this:
var vm = SimpleIoc.Default.GetInstance<IMessageViewModel>();
// instead of doing this
var vm = new MessageViewModel();
//do stuff with vm
}
}
Whether to use interface bases approach to separate the view models from each other is the design decision based on complexity of your application.
If you want to dynamically create instance of IMessageViewModel inside IConvesationViewModel; I would recommend instead of referring to IoC container in your ViewModel class inject a factory for creating IMessageViewModel in the ConversationViewModel constructor. Later you can use this factory to create instances of IMessageViewModel. A simple implementation of factory could be Func delegate.
public class ConversationViewModel
{
private Func<IMessageViewModel> _messageViewModelFactory;
public ConversationViewModel(Func<IMessageViewModel> messageViewModelFactory)
{
_messageViewModelFactory = messageViewModelFactory;
}
public void MessageReceived(string data) {
var messageViewModel = _messageViewModelFactory();
}
}
This way you are exposing dependencies of your ConversationViewModel class through the constrctor instead of hiding them inside the class implementation.
The IoC containers like Autofac provide way to inject Func in the constructor when you create object of ConversationViewModel using it.
I believe a better way to do that is by using interfaces. You can have both your real and mock ViewModels implement the same interface and use that interface everywhere where you would use a ViewModel class.
If it was me and I may not have all the information about your application but I would have a single ViewModel IConversationViewModel. And in the IConversationViewModel I would have a collection of IMessageModel instances. I would not go nesting ViewModels.
What you can do is create the MessageViewModel immediately in ViewModelLocator and register for receiving messages in MessageViewModel using the MVVMLight MessengerInstance in its constructor. Something like this:
public class ViewModelLocator
{
public class ViewModelLocator()
{
//creates instance immediately
SimpleIoc.Default.Register<MessageViewModel>(true);
}
}
public class MessageViewModel:ViewModelBase
{
public MessageViewModel()
{
MessengerInstance.Register<string>(this,DoSomething);
}
public void DoSomething(string data)
{
//do stuff
}
}
public class ConversationViewModel:ViewModelBase
{
public void MessageReceived(string data)
{
MessengerInstance.Send<string>(data);//this will trigger DoSomething in MessageViewModel
}
}

C# UserControl multiple inheritance

I would like to create my own user controls which implement more properties and methods than the ones given from .NET Framework. First of all I would like to have a custom UserControl class, which I would call MyUserControl and of course will inherit from UserControl:
public class MyUserControl : UserControl {
public MyUserControl() : base() {
}
...
}
After that I would like to have my own MyTestBox, which will inherit from TextBox.
public class MyTextBox : TextBox {
public MyTextBox() : base() {
}
...
}
My problem now is that I want MyTextBox to inherit from MyUserControl also, because I have properties and methods implemented there, that I need in MyTextBox also.
The only solution I could think of is to make MyTextBox inherit just from MyUserControl and not from TextBox, but add a TextBox in it in the constructor:
public class MyTextBox : MyUserControl {
public MyTextBox() : base() {
Add(new TextBox());
}
...
}
but then I would have to re-implement every single property and method of TextBox in MyTextBox. Is there a better way to achieve this?
Separate out all the common code into a separate class and use delegation to handle it.
ie. something like this:
public class MyUserControl : UserControl
{
private MyExtraControlCode _Extras;
public MyUserControl()
{
_Extras = new MyExtraControlCode(this);
}
public int GetInt32Value()
{
return _Extras.GetInt32Value();
}
}
public class MyTextBox : TextBox
{
private MyExtraControlCode _Extras;
public MyTextBox()
{
_Extras = new MyExtraControlCode(this);
}
public int GetInt32Value()
{
return _Extras.GetInt32Value();
}
}
or something similar.
Not as straightforward, but multiple inheritance is just not supported in .NET.
After looking at the problem in more detail, I finally reached to this conclusion: There are 3 ways to achieve what I want, but all of them require some extra implementation.
First of all multiple inheritance is not supported in C# .NET. In my case it would make things more complex anyway, because in MyTextBox I wanted in a way to be able to access custom properties/methods from both MyUserControl and TextBox. But both of these classes inherit from Component Class, so multiple inheritance (if it were possible) would mess thing up here. The question I asked myself is: What do you finally want to do? The answer is, that I simply want to be able to "extend" all my UserControls (or Components) in general (namely regarding all UserControls) and also specifically (namely regarding TextBox, Combobox, ListView, etc), so that when I create a MyTextBox object, I could do both:
myTextBox.MyUserControlStuff();
and
myTextBox.TextBoxStuff();
So here are my solutions:
1. Use extensions
and extend UserControl (or Component) class. In that case, I have:
public class MyTextBox : TextBox
{
public void MyTextBoxStuff()
{
...
}
}
public static class UserControlExtensions
{
public static void MyUserControlStuff(this UserControl control)
{
...
}
}
And MyTextBox can also do all UserControl stuff and TextBox stuff
Downside: every (specific) extension method applies to UserControl also.
2. Use an interface
public class MyTextBox : TextBox, IUserControlStuff
{
public void MyTextBoxStuff()
{
...
}
public void MyUserControlStuff()
{
...
}
}
public interface IUserControlStuff
{
public void MyUserControlStuff();
}
Downside: I will have to re-implement MyUserControlStuff each time again and again.
3. Use an "extra code" class and make it a member of each custom UserControl & MyUserControl (like #Mr.Karlsen suggested)
See the answer of #Mr.Karlsen for more details. I would say this is the best solution, but it has its downside
Downside: A little messy. A developer, new to my project would find it difficult to understand when seeing it for the first time. I would personally avoid it.
Finally I decided to go with the interface, because my UserControl properties/methods are specific to my needs so it wouldn't be good to extend UserControl with "specific" stuff. I have to write more code in my case and even re-write the same code while implementing my interface's methods, which I really hate. Anyway!!

Best way to eliminate inheritance "magic" in C# winforms?

I'm working on a legacy application wich has some flaws due to inheritance, but I'm struggling to solve it properly.
At the moment the structure of the WinForms looks like this:
BaseForm
ListViewForm : BaseForm
ListViewFormReadOnly : ListViewForm
ListViewFormWithDetailForm : ListViewForm
DetailForm : BaseForm
ConcreteForm : ListViewFormWithDetailForm
There is a method inside the BaseForm which is called sth like protected virtual void InitializeMyStuff() which is overwritten in the inherited instances.
e.g.
public class BaseForm {
public BaseForm() {
//.. do stuff
//.. do other stuff like initialize DB connection or read app.config values and initialize properties..
}
public virtual void InitializeMyStuff() {
throw new NotImplementedException();
}
}
public class ListViewForm : BaseForm {
protected BindingSource GridBindingSource { get; set; }
public ListViewForm {
//do special stuff like adding the grid and some buttons
}
}
public class ConcreteForm : ListViewForm {
public override void InitializeMyStuff() {
GridBindingSource = my_bindingSource;
SomeOtherUsefulProperty = myValue;
Foo = new Bar();
// etc.
}
}
//Usage:
var myForm = new ConcreteForm();
myForm.InitializeMyStuff();
As you can imagine this creates some problems like:
- "What things do I have to set at this point for the form to work"
- "What things may not be initialized yet?"
- "Which properties and method calls are at my disposal yet"
and some other interesting thoughts about what may be going on in that magic blackbox.
How can I refactor this so that it gets more clear what is happening? Remember that this is a project with about 150 or more concrete forms.
My initial thought was to encapsulate those magic properties like the GridBindingSource for example into an object (e.g. FormConfiguration) and make it private in the BaseForm.
e.g. something like that
public class BaseForm {
private FormConfigObject _formConfig = new FormConfigObject();
protected override void OnLoad()
{
InitializeMyStuff(_formConfig);
}
protected virtual void InitializeMyStuff(FormConfigObject config)
{}
}
The problem I have here is: the FormConfig object of the ListForm would have to have other properties for example, like GridBindingSource but I can't just change the signature in the derived classes to an ListFormConfigObject isntead of the FormConfigObject..
Can anybody suggest possible solutions to get out of this dilemma?
// Edit: straightnened out the code to what actually happens and getting rid of the virtual call in the constructor violation.
The main question is this: are there any objects inside BaseForm that:
are required to be initialized in BaseForm's constructor
depend on the concrete implementation of the subclasses
If such objects exist then probably they should be made polymorphic, and passed into BaseForm's constructor from subclasses.
A simple example, on of many possible scenarios:
abstract class RandomPicture
{
public RandomPicture()
{
shapes = new List<Shape>();
InitializeRandomShapes();
// do some initial drawing calculations
}
protected abstract void InitializeRandomShapes();
protected List<Shape> shapes;
}
//... subclasses initialize the shapes
This can be changed to:
abstract class RandomPicture
{
public RandomPicture(AbstractShapeCollection shapeCollection)
{
shapes = shapeCollection;
// do some initial drawing calculations
}
private AbstractShapeCollection shapes;
}
And now subclasses provide the required information through the abstract object, so the base class can proceed with it's task.
Splitting information into various objects like this is a good refactoring start, as you create more smaller objects, that are easier to test and manage and reveal the underlying structure of a mess that you've encountered. It helps also to reduce the number of violations of Single Responsibility Principle.

Ninject Form Clarification

I have a ModuleLoader : NinjectModule which is where I bind everything.
Firstly I use
Bind<Form>().To<Main>();
to Bind a System.Windows.Forms.Form to my Main form.
Is this correct?
Secondly in the Program.cs I use this:
_mainKernel = new StandardKernel(new ModuleLoader());
var form = _mainKernel.Get<Main>();
Where _mainKernel is a ninject standard kernel.
Then I use Application.Run(form)
Is this correct?
I'm unsure as to what to bind together when it comes to Windows.Forms.
Thanks for any help.
You shouldn't really be binding to System.Windows.Forms.Form. Ninject is primarily meant for binding interfaces to concrete types so that you can pass around dependencies as interfaces and switch out the concrete implementation at runtime/during tests.
If you just want to use Ninject to create your Form in this way though, you'd simply use Bind<MyForm>().ToSelf() then do kernel.Get<MyForm>(). If you are requesting the concrete type directly though and it doesn't take any dependencies, there's not much point in using Ninject to initialise it.
In your situation, if your form implements an interface then you would do: Bind<IMainForm>().To<MainForm>() and request the interface type from Ninject. Usually your interface shouldn't be bound to the concept of a "form" though, it should be agnostic of the implementation (so later you could produce a CLI and website version and simply swap the Ninject bindings).
You could use the Model-View-Presenter design pattern (or a variant) to achieve this like:
public interface IUserView
{
string FirstName { get; }
string LastName { get; }
}
public class UserForm : IUserView, Form
{
//initialise all your Form controls here
public string FirstName
{
get { return this.txtFirstName.Text; }
}
public string LastName
{
get { return this.txtLastName.Text; }
}
}
public class UserController
{
private readonly IUserView view;
public UserController(IUserView view)
{
this.view = view;
}
public void DoSomething()
{
Console.WriteLine("{0} {1}", view.FirstName, view.LastName);
}
}
Bind<IUserView>().To<UserForm>();
Bind<UserController>().ToSelf();
//will inject a UserForm automatically, in the MVP pattern the view would inject itself though
UserController uc = kernel.Get<UserController>();
uc.DoSomething();

Categories