How to "bypass" constructor call if instance is not null (WinForms designer code) - winforms

When we place a component on a Windows Form, the default behavior for the designer is to serialize a contructor call in the IntializeComponent method of the form.
Is there any way to have a custom serializer output the following code:
if (componentInstance == null)
componentInstance = new componentClass();
instead of just:
componentInstance = new componentClass();
The reason is simply that the component is instantiated before the Form, and I want to pass it to one of the Form's constructors.
The component is designed to allow quick selection of properties (in the same way you add your DataBinding to Controls) at design time, but the call to the constructor in InitializeComponent() assumes I want to create a new instance when in fact, I already have a reference to it. By checking for null, then it would work both at design time and run time.
Thank you.

It's simple really - don't use the Form Designer to add your component to the Winform. Instead manually add a member variable of the component type that you are after into the underlying code (.cs) file and handle it directly in code.
Added in response to your comment
As far as I am aware, there is no way in which you can avoid this behaviour for components placed at design time. You could delete references from initialise components method, but this may be overwritten by the designer at some point.
Taking into account your comment below, then I would suggest that you have a member variable on the form (as suggested above) and then set this to refer to the design time component if the runtime variable is null or the runtime variable if it isn't.
i.e.
CSomeComponentType liveComponent;
...
this.liveComponent = runtimeVariable;
if(this.liveComponent == null)
{
this.liveComponent = this.designTimeComponent;
}

Related

How can I get the rootNodeID of react element

I need to capture event depend on whether the event target is a special view.
Something like view._rootNodeID === 'event.dispatchMarker'.
But there seems to be no way to get _rootNodeID because the only reference I can get is not the actual ReactNativeBaseComponent but rather something like baking data instance used to construct ReactNativeBaseComponent . And ReactNativeBaseComponent is the one really owns _rootNodeID, if I understand source code correctly.
I can alter react-native source code to achieve what I want but I want to make sure there is no better way.
ReactInstanceMap exists for this.
const ReactInstanceMap = require('ReactInstanceMap');
const inst = ReactInstanceMap.get(view);
view === inst.getPublicInstance();
It seems I always tend to complicate things...Why wouldn't I handle the touch event in that special view directly?
And I must be blind to not notice a property named _reactInternalInstance to refer to the actual element. Although doing so will breaks encapsulation.

extjs - dot notation to bracket {} notation?

not sure that that is a good title ...
I can get code behind a button to:
TabBar.activeTab.setTitle("New Tab");
but I need to do something like:
TabBar.activeTab.items = { title: "New Tab"
};
so I can eventually automate several tab properties in a loop:
TabBar.activeTab.items = { [key]: [value]
};
Am I correct in thinking config and items can only be used on construct()? Is there a way of doing the above? tia.
It depends on the implementation of the component and config property in question whether it can simply be set or requires a method call to be applied.
You are correct that in ExtJs many config properties are interpreted at construction time. Some are interpreted at render time. Once an Ext.Component is rendered almost all properties require an explicit method call to be applied correctly.
In general, I recommend to always use a method call to change a property after construction time if available in order to not break the inner workings of the component. If you look at the implementation of Ext.panel.Panel#setTitle you can see that there is a lot of stuff going on under the hood, e.g. event firing, etc.
ExtJs 4 configuration
Ext 4 introduced an explicit 'config' mechanism that might serve your purpose. However, my understanding is that most ExtJs components are not (yet?) using it.
Check out '2. Configuration' in the ExtJs Class System Guide
Create objects from xtype/config literals
If you want to add new components to a container (e.g. tabs to a tab panel) it would be rather easy to accomplish.
Use Ext.ComponentManager#create (see [docs][2]) to create an actual component object/instance from your config literal.
Ext.container.Container#add actually calls this method internally, so you can simply pass config objects to the add method.
If you want to remove or add tabs to a panel, there is now way around calling the proper methods.
applyConfig()
Of course you could always implement your own applyConfig method that supports changing certain component configuration properties at runtime by 'translating' the config into the proper method calls.

Calling .Net function on UI test instance in TestComplete

I have a simple wpf app which has a button that increments a value on clicking. I also have a function that returns the latest value. The default value is 5. I also have a UI test in testcomplete that clicks the button 3 times (so 8). I need to call the .Net function to get this value and assert it. Below is my test code.
After some search I figured out the CLRbridge details and implemented it. However, As you can see below, the UI test instance and the instance on which I am claling the function are different. So, the function returns 5.
My question is, how do I invoke the function from the same instance loaded by testcomplete. Or am I going completely the wrong way for this? I tried both script and UI test with if..then, nothing worked. I have tried both direct instance and calling on the appdomain, both doesnt seem to work.
NOTE: I do understand that I can display the value in a UI control and validate the control. However, i am specifically trying this out for a more complex testing functionality we need in a project.
function Test2()
{
var Increment;
Increment = 0;
//Runs the "TCompTest" tested application.
TestedApps.TCompTest.Run();
//Clicks the 'button1' button.
Aliases.TCompTest.HwndSource_MainWindow.MainWindow.Grid.button1.ClickButton();
//Clicks the 'button1' button.
Aliases.TCompTest.HwndSource_MainWindow.MainWindow.Grid.button1.ClickButton();
//Clicks the 'button1' button.
Aliases.TCompTest.HwndSource_MainWindow.MainWindow.Grid.button1.ClickButton();
//Increment = dotNET.Incrementer.Incr1.zctor().IntValue(true);
Increment = dotNET.Incrementer.Incr1.zctor().IntValue(true);
**OR**
Increment = Sys.Process("TCompTest").AppDomain("TCompTest.exe").dotNET.Incrementer.Incr1.zctor().IntValue(true)
// if(Increment == 8)
// {//Posts an information message to the test log.
Log.Message(Increment);
// }
//Closes the 'HwndSource_MainWindow' window.
Aliases.TCompTest.HwndSource_MainWindow.Close();
}
It should be possible to do what you need from TestComplete. But first of all, to avoid misunderstanding, let me explain the problems with the approaches you tried:
Addressing a class through the "dotNET" object.
When you do this, TestComplete initializes .NET in its service process, loads the specified assembly into it, and works with the classes of this assembly loaded to TestComplete's AppDomain (though living in a separate process). This means that this instance of your assembly has nothing to do with your tested application. So, you can't access your application's data through the dotNET object.
Addressing the Incrementer assembly through the tested application's AppDomain.
OK, in this case you are closer to a solution - you work with the AppDomain of the tested application, so you can access the application's data. However, in your code, you create a new instance of the Incr1 class (via calling zctor). This means that the new class instance will initialize its counter in the constructor, and it will be 5. And this is the value you are getting in your code.
So, the right approach:
Unless the counter field of the Incr1 class containing the current counter value is a static field, you need to address an existing object of the Incr1 class to get the current value of the property, not to create a new class instance. The actual implementation will depend on where you are storing the Incr1 class instance reference in your application. Let's suppose, you store the reference in the Counter property of the MainWindow object:
// Creating an instance of the class somewhere in your code
MainWindow.Counter = new Incr1();
// ...
// And this line of code is in the button click handler
MainWindow.Counter.Increment();
In the described case, you will be able to get the current counter value in your TestComplete script as follows:
var MainWnd = Aliases.TCompTest.HwndSource_MainWindow.MainWindow;
Log.Message(MainWnd.Counter.IntValue(true));
If your setup is different, please describe it - I will try to help accordingly.

Non-blocking lazy-loaded properties in model of MVVM

I'm fairly new to MVVM, so please excuse me if this problem has a well-known solution.
We are building a bunch of model classes which have some core properties that are loaded up-front, as well as some additional properties which could be lazy-loaded on demand by making a web API call (update: to clarify, it would be a web API call per lazily-loaded property).
Rather than having multiple models, it seems sensible to have a single model with the lazy-loading logic in there. However, it also seems that the lazy-loaded properties should not block when accessed, so that when the View binds to the ViewModel and it binds to the Model, we don't block the UI thread.
As such, I was thinking of a pattern something along the lines of when a lazy property on the Model is accessed it begins an asynchronous fetch and then immediately returns a default value (e.g. null). When the asynchronous fetch is complete, it will raise a PropertyChanged event so that the ViewModel/View can re-bind to the fetched value.
I've tried this out and it seems to work quite nicely, but was wondering:
Are there any pitfalls to this approach that I haven't found out about yet, but will run into as the app increases in complexity?
Is there an existing solution to this problem either built into the framework, or which is widely used as part of a 3rd party framework?
I did something like this in the past and the one thing I kept forgetting about is you can't call your async property through any kind of code behind and expect it to have a value.
So if I lazy-load a list of Customer.Products, I can't reference Customer.Products.Count in the code-behind because the first time it's called the value is NULL or 0 (depending on if I create a blank collection or not)
Other than that, it worked great for the bindings. I was using the Async CTP library for making my async calls, which I found was absolutely wonderful for something like this.
public ObservableCollection<Products> Products
{
get
{
if (_products == null)
LoadProductsAsync();
return _products;
}
set { ... }
}
private async void LoadProductsAsync()
{
Products = await DAL.LoadProducts(CustomerId);
}
Update
I remember another thing I had issues with was data that actually was NULL. If Customer.Products actually returned a NULL value from the server, I needed to know that the async method had run correctly and that the actual value was null so that it didn't re-run the async method.
I also didn't want the async method to get run twice if someone called the Get method a 2nd time before the first async call had completed.
I solved this at the time by having an Is[AsyncPropertyName]Loading/ed property for every async property and setting it to true during the first async call, but I wasn't really happy about having to create an extra property for all async properties.

Cannot reference global class instance in SSRS report Header/Footer?

I have a report which uses a custom assembly for purposes of localization/globalization.
I am creating my translation object (I'll call it "dictionary") and initializing a Dictionary property of this object in the custom code OnInit() override.
Everything works fine in report body, but when I try to reference the object I describe above in either the Report Header or Report Footer- it is not accessible (object ref is not set to instance of obj error..).
Can anyone either tell me why this is or how I might be able to workaround it? I really don't want to have to re-initialize this localization object separately for the Header and Footer. I was under the impression custom code class instances were accessible anywhere within the report definition.
Thanks in advance for any light anyone can shed on this.
I am not sure of your implementation, but the recommendation is to use static methods rather than instances. Understood that this is not always the best case for each design, but in your case, it sounds like you could use a static method and then in that case, when called from your header and footer, the custom assembly static method will initialize all data. It will be easier that putting the implementation or instance creation in the RDL.
This appears to just be by design. A custom class instance is not accessible to the Report Header or Footer. My solution was to simply add a check to the custom code function which the report expressions call (psuedo-code):
If IsNothing(myCustObj)
{
///initialize myCustObj
}
That seems to be the best workaround.

Resources