I'm trying to create a non-standard top navigation bar for use throughout my application. To achieve this I've been trying to subclass UINavigationController and UINavigationBar
I have a custom NavigationController class
partial class ZooNavigationController : UINavigationController
{
public ZooNavigationController (IntPtr handle) : base (typeof(TopNavBar), null)
{
this.Handle = handle;
}
}
which points to the base constructor
public UINavigationController (Type navigationBarType, Type toolbarType);
for my custom UINavigationBar class TopNavBar which is something like...
public class TopNavBar : UINavigationBar
{
public TopNavBar ()
{
InitCustom ();
}
public void InitCustom(){
this.BackgroundColor = UIColor.Red;
// a bunch more custom stuff
}
}
The problem is, TopNavBar is never called when I run this. If I try to adjust my constructor to look like this:
public ZooNavigationController (IntPtr handle) : base (typeof(TopNavBar), null)
{
this.Handle = handle;
TopNavBar test = (TopNavBar)this.NavigationBar;
}
I get a runtime exception that it can't cast the types, so it seems that it's ignoring my call specifying the UINavigationBar type.
Can anyone help me out with what I'm missing here?
EDIT in the end it turns out I was missing the fact that you can set a custom UINavigationBar inside the storyboard. Combining that with the miguel's answer I ended up with the class
partial class TopNavBar : UINavigationBar
{
public TopNavBar(IntPtr test) : base(test) {
}
[Export ("initWithCoder:")]
public TopNavBar (NSCoder coder) : base (coder) {
InitCustom ();
}
}
The IntPtr constructor is called in response to the object being created by Objective-C and surfaced to C#. This in general is not the way that these classes are instantiated.
The first question that you have to ask yourself is: who is creating the instance of your class?
You create the instance of this class from C#: you call a constructor with the proper parameters.
Being created during deserialization (for example, loading from a storyboard, XIB, or your own archived data), then you need to provide the constructor that takes an NSCoder parameter.
Having your instance recreated on demand (may indicate a problem, because it means that your object was destroyed, but Objective-C kept a reference to it, and now it is being resurfaced again), the IntPtr constructor.
In your example above, there is a mistake: you are overriding the IntPtr constructor, which should only ever call into the base class IntPtr constructor (since it means "I have a pointer to the real object in objective-c, create a wrapper for it").
My guess is that you are using C#, so in that case, what you want is to provide a new constructor that takes no arguments:
public ZooNavigationController () : base (typeof (YourNavigation), typeof(YourBar)) {
// Your own initialization goes here
}
Related
I want to create a parent class who handles setting up all the control properties for a map, because I need that functionality in multiple forms. Since you can not pass anything besides parameters to your child function to the parent class, I have no idea how to continue. Setting up an extra method where you have to add the control to the parent class feels kind of unclean because I need to check the reference each time I call it.
Maybe you have some ideas how to implement this problem. Thanks!
public abstract class MapForm
{
protected MapForm(GMapControl mapControl)
{
MapControl = mapControl;
}
...
}
public class TestForm : MapForm
{
public TestForm(string searchValue = String.Empty) :
Base(this.mapControl) // cant do that of course
{}
...
}
I have the following class:
class Base<T> where T : Base<T>
{
protected static string Source;
public static List<T> Read()
{
return GetResource(Source);
}
}
I want this class as baseclass for its functionality but every derived class has to have a different Source. My problem is that I can't assure the Source is set before Read is called. I know I could ask if the Source is set before GetResource is called but that's not the point. I need it to be set before any static member of my class is called.
Generic parameters can't have static Members so I can't take it from there.
I tried setting the Source in the derived class's static constructor but that will only be called when I call a member that is in the derived class and not in the Base.
I tried using a overridable method inside of the static Base constructor but such a method has to be static as well and static methods can't be overwritten.
When I set the Source manually, there is a chance that the Read-Function has already been called, so I have to set the Source before it can be called.
I know I could give Source as a parameter in Read but I want Read to be used without parameters.
Is there any way I can assure that the Source is Set before any other Member of my class is called, so that any dependent code is inside the derived class and doesn't have to be called by anyone using a derived class?
I basically want it to work like this:
class Derived : Base<Derived>
{
// somehow set Source
Source = "This is my source";
}
class User
{
private List<Derived> MyResources;
public User()
{
MyResources = Derived.Read();
}
}
Note: the Source is basically a SQL statement so an Attribute or something like that wont be sufficient I think.
Ok, I found an answer. It is not as pretty as I hoped it would be but its the best I could come up with.
I will use an interface to force an Instance of T to have a certain method that provides my source.
interface ISource
{
string GetSource();
}
I then implement that into my base class as such:
class Base<T> where T : Base<T>, ISource, new()
{
public static List<T> Read()
{
// here I create an Instance to be able to call the Methods of T
string source = (new T()).GetSource();
return GetResource(source);
}
}
The derived class:
class Derived : Base<Derived>, ISource
{
public string GetSource()
{
return "This specific source";
}
}
Usage as such:
class User
{
public User()
{
List<Derived> myResources = Derived.Read();
}
}
This of course will lead to every instance of Derived having the GetSource-method but for my scenario thats not a big deal.
Also, since it creates an instance in the Read-method, this could be time consuming depending on the constructor of Derived. In my scenario it only has the standard constructor.
So use with caution.
The question title seems a little bit odd doesn't it. Anyway. So I have one base class which has some private fields, protected properties and a single constructor that takes one argument and I have several sub classes of that base class. whenever any of those subclass methods are called the sub classes are required to be instantiated and after the method is done executed the object is destroyed so if the method will be called again new instance of the class should be made. (Its a WCF service) Now, the thing I want to do is the following. whenever the certain sub class constructor is called I call the base class constructor explicitly with some certain parameter (different for every sub class, Note: no sub class methods are the same), When the base class constructor is called I want to check something according to that argument and if it passes the check then I want to allow the execution of sub class method. In any other case I want it NOT to run the sub class method. So I want something like this. when the method is called the sub class has to be constructed and for that, base class has to be constructed as well and if the check fails in the base class' constructor I want to prevent that method from running. I can just have a bool property and set it in base class' constructor and check it on every method call. but I want to make something more general. May be the way that I'm suggesting Is not right either. So you understand what I want I guess. Any suggestion would be appriciated. thanks in advance
class BaseClass
{
private bool _isValid;
private SomeService someService;
public BaseClass(SomeEnum value)
{
someService = new SomeService();
if (someService.Validate(value))
{
_isValid = true;
}
}
protected internal bool IsValid { get { return _isValid; } }
}
class SubClass : BaseClass
{
// object declaration
public SubClass () : base(SomeEnum.SomeValue)
{
// constructing some objects here
}
public Response Operation('parametereGoHere')
{
if (IsValid)
{
// perform operation. construct Response object and return it
}
}
// other methods omitted.
}
So whenever the Operation() method is called SubClass has to be constructed which causes the BaseClass to be constructed and the base class sets the value of _isValid which is then use to check for validity, but I wanted to make something more general. lets that instead of just setting the value of _isValid to true just do nothing or set some other properties and if the Valiate() failed just stop the execution and don't to anything at all. In this case the calling routing wouldn't be able to call Operation() if we somehow managed to stop the construction of class. If it's not possible I'm perfectly happy with the solution I have right now. But if it is I will be glad to see that. Note: In every sub class, methods are different and I have to check IsValid to allow the execution of method.
You should be able to use the out parameter to get the constructor to return a value.
Very hard to follow what you want, but it sounds like you want a case where the base constructor doesn't do anything sometimes. Then simply make a base constructor that doesn't do anything, and call it (with the : base() call). Use a dummy argument if necessary.
class A {
public A() { a= 1; }
public A(double dummy); { }
}
class B
public B() : base() { // calls the base constructor that does something
}
public B(int) : base(1.0) {// class the base construct that does nothing
}
}
Its been a while but i need to convert some custom code into C# (i think it was called emeralds or something somebody else gave to me). there is a certain method that takes a class(any class without any object conversions). this is the code im trying to convert.
class management
Accessor current_class
Accessor class_Stack
def call(next_class) #method, called global, takes a "class" instead
#of a variable, kinda odd
stack.push(current_class) #stack handling
current_class = next_class.new #makes a new instance of specified next_class
end
end
next_class seems to be any class related to a base class and assigns a new instance of them to a variable called currentClass. there are other "methods" that do something similar. I've tried setting the parameter type to "object", but loses all the the "next_class" attributes that are needed. this is my attempt at it
public class management {
public Stack stack;
public Someclass currentClass;
public void Call(object nextClass) {
stack.push(currentClass); // stack handling
currentClass = new nextClass(); // conversion exception, otherwise loss of type
}
}
IS this even possible in C#
another thing this language seems to able to keep attributes(methods too) from Child classes when you cast them as a base class. e.g cast green bikes as just bikes but it will still be green
can somebody point me in the right direction here? or do i need to rewrite it and change the way it does things?
What you want is Generics and I think also, based on the fact that you call a method, Interfaces.
So your Interface will define "new" and the Class will inherit from the interface.
You can then pass the class as a generic and call the Interface method of "new" on it.
So;
public interface IMyInterface
{
void newMethod();
}
public class MyClass1 : IMyInterface
{
public void newMethod()
{
//Do what the method says it will do.
}
}
public class Class1
{
public Class1()
{
MyClass1 classToSend = new MyClass1();
test<IMyInterface>(classToSend);
}
public void test<T>(T MyClass) where T : IMyInterface
{
MyClass.newMethod();
}
}
EDIT
And check out "dynamic" in C# 4.0. I say this because if you don't know what the method is until runtime you can define it as dynamic and you are basically telling the compiler that "trust me the method will be there".
This is in case you can't use generics because the methods you call will be different for each class.
I've been searching all over for the answer to this question, and while I realize it's likely very trivial, somehow the answer eludes me.
I need to show a second window (launched from clicking a menu item, if that matters). I know perfectly well how to do this with winforms, but I'm not sure what the monomac/NSWindow equivalent is. I need to do this:
MyWindowClass myWindow = new MyWindowClass();
myWindow.Show();
The best info I can find on the subject says that the following should work:
MyWindowClass myWindow = new MyWindowClass();
myWindow.MakeKeyAndOrderFront(this);
But when I try that, it tells me that MyWindowClass() needs an overload, so I look at the constructor and see that it's asking for an IntPtr. Not knowing any better, I try this:
MyWindowClass myWindow = new MyWindowClass(new IntPtr());
myWindow.MakeKeyAndOrderFront(this);
This code will run without error, yet nothing happens when I try to launch the window.
I'm sure I'm just making a silly mistake, but I just haven't been able to find anything on the subject. Any help would be greatly appreciated.
Edit: For reference, here's the relevant portion of the constructor:
public MyWindowClass (IntPtr handle) : base (handle)
{
Initialize ();
}
Additional info: I'm trying to run the code above from within AppDelegate.cs in the following method:
partial void showWindow (MonoMac.Foundation.NSObject sender){
MyWindowClass myWindow = new MyWindowClass(new IntPtr());
myWindow.MakeKeyAndOrderFront(this);
}
EVEN MORE CODE AHOY:
public partial class ViewPaths : MonoMac.AppKit.NSWindow
{
#region Constructors
public ViewPaths ()
{
Initialize();
}
// Called when created from unmanaged code
public ViewPaths (IntPtr handle) : base (handle)
{
Initialize ();
}
// Called when created directly from a XIB file
[Export ("initWithCoder:")]
public ViewPaths (NSCoder coder) : base (coder)
{
Initialize ();
}
// Shared initialization code
void Initialize ()
{
}
#endregion
}
And then the actual instantiation:
public partial class AppDelegate : NSApplicationDelegate
{
MainWindowController mainWindowController;
ViewPaths display;
public AppDelegate ()
{
}
public override void FinishedLaunching (NSObject notification)
{
mainWindowController = new MainWindowController ();
mainWindowController.Window.MakeKeyAndOrderFront (this);
}
partial void viewPaths (MonoMac.Foundation.NSObject sender){
display = new ViewPaths();
display.MakeKeyAndOrderFront(this);
}
}
}
This shows a window with no UI elements of any kind.
Just add a default constructor without the handle parameter. Make sure MyWindowClass subclasses NSWindow and it should work.
Also, you may need to keep a reference to your myWindow around - so that it does not get garbage collected.
For clarity, here's the final code that solved the problem, should anyone else ever google this:
Since I had created a new monomac window with a controller, I needed to create an instance of that controller, and show the controller's window:
MyWindowController myWindow = new MyWindowController();
myWindow.Window.MakeKeyAndOrderFront(this);
This did not need a new constructor without a handle parameter implemented - that solution was working around the problem I'd created by instantiating the incorrect thing.