Initialization order of static variables in Flex causing bug - apache-flex

I've got a component written for my app by a third party developer and am trying to integrate it, but I've found a bug that seems like it's either a compiler bug, or there's something with how Flex and static variables work that I wasn't aware of.
Basically, I have this:
public class ModeChangeController {
public static const DISPLAY_MODE:String = "DisplayMode";
}
public class Events {
public static const DISPLAY_MODE:String = "DisplayMode";
public static function myStaticFunction( viewState:String = null):void {
//Empty
}
}
<?xml version="1.0" encoding="utf-8"?>
<s:BorderContainer /*snip*/ >
<fx:Script><![CDATA[
import mypackage.sub1.ModeChangeController;
import mypackage.sub2.Events;
private function showInitialView():void {
// Variant 1
Events.myStaticFunction( Events.DISPLAY_MODE);
// Variant 2
Events.myStaticFunction( ModeChangeController.DISPLAY_MODE);
}
]]></fx:Script>
}
If I use //V2 (i.e. comment out V1), a bug occurs at the startup of the application (some TextFields are uneditable and contains no text), but with //V1 and not V2, it works fine. If I comment out both, that also works fine (I don't get the TextField bug).
It took me a while to figure out that it was that static const String that was causing the issue, but I'm still not sure why or if there's something I can do about it except for just moving the DISPLAY_MODE to Events (which is what I've done at the moment, but it's not a particularly nice solution).
There are no errors in the log. The order of the includes in my BorderContainer code doesn't matter. I've googled for "as3/flex static initialization order" but haven't found anything.
Does anyone know what the problem is?
Clarification: showInitialView() never gets called. It doesn't get there before the other bug shows up. Just having the V2 line there causes the problem.
Update: I've fixed my problem with the TextInput strings not showing: Turns out that adding the component caused the Tahoma font to not show up. However, setting the font-weight to bold fixed that problem, or switching to Arial. With that said, the original question still stands, because when I ran it without V2, it found Tahoma with normal font-weight.

It's not the static string. I tested it myself without a problem. I was skeptical of your issue since the flash static vars would get created when the application is loaded no matter what and the variable would be available.
I believe the problem has nothing to do with the static var but with something else causing an error. It seems that you don't have a version of Flash Player debug by your description. Get it, debug your application line by line and see what the problem is.

Related

Qt5 dynamic translation issues for C++ defined properties

I am currently working on somebody else code and I need to fix a bug linked with dynamic translation.
When the language is changed, the Loader is reloaded, it works but it generates unwanted effects (including the bug mentioned above).
So I tried to look for a way to dynamically change the translation without reloading everything.
I added m_engine->retranslate() in my switchLanguage function and this works perfectly, but only for texts directly defined in QML files. The thing is there is also a lot of text defined with setContextProperty in the C++ main controller class, and for them, it doesn't work at all (which seems pretty normal since m_engine is a QQmlApplicationEngine).
I don't see how I can simply force these texts to retranslate too. I have them in pretty much every controller function and they are used by different QML files. I am afraid that there will be no other choice but to change completely the way translation is managed. I hope advanced programmers can help me with this.
Other information:
I work with 5.13.0 version of Qt.
I don't use Designer and cannot use ui.retranslateUi().
It's hard to tell how your main controller class looks like, so here is a short general answer.
You can install an eventFilter and listen for LanguageChange.
In constructor of "main controller class", add this:
auto *core = QCoreApplication::instance();
if(core != nullptr)
{
core->installEventFilter(this);
}
Then add a function to your class:
bool MainControllerClass::eventFilter(QObject *watched, QEvent *event)
{
Q_UNUSED(watched);
if(event->type() == QEvent::LanguageChange)
{
//set properties again or emit property changed signals
}
}

Unable to override OnApplyTemplate

I'm trying to override the NavigationView behavior:
public partial class CustomizableNavigationView : NavigationView
{
public CustomizableNavigationView()
{
// This gets called
}
protected override void OnApplyTemplate()
{
// This doesn't
}
}
It works on UWP, but not on Android. On Android, it doesn't call OnApplyTemplate and the screen remains blank, there's not content. Questions:
Why doesn't OnApplyTemplate get called on Android? I see that here: https://platform.uno/docs/articles/implemented/windows-ui-xaml-frameworkelement.html it says OnApplyTemplate() is on all platforms
There's no error or anything displayed in the Output panne in VS while running with debugger. Should there be any in this case? Do I need to enable something to log errors?
I noticed that if I don't use partial it gaves me error saying partial is required. This is required only on Android, why is that? A more in-depth explanation would help a lot to understand how things work.
Once I figure out why OnApplyTemplate is not called, I want to do this:
base.OnApplyTemplate();
var settingsItem = (NavigationViewItem)GetTemplateChild("SettingsNavPaneItem");
settingsItem.Content = "Custom text";
My hunch is this won't work on Android. Am I correct? :)
Jerome's answer explains why OnApplyTemplate() was not getting called, to address your other questions:
You can configure logging filters for Uno, this is normally defined in App.xaml.cs. Warnings should be logged by default.
The partial is required because Uno does some code-gen behind the scenes to create plumbing methods used by the Xamarin runtime. Specifically because the control is ultimately inheriting from ViewGroup on Android, it's a native object, and requires special constructors that are used only by Xamarin's interop layer. There's some documentation in progress on this.
Try it and see. :) GetTemplateChild() is supported, and setting ContentControl.Content in this way is supported, so I would expect it to work.
At current version (1.45 and below), the application of styles is behaving differently from UWP. We're keeping track of this in this issue.
The gist of the issue is that Uno resolves the style using the current type and not DefaultStyleKey, and cannot find an implicit style for CustomizableNavigationView.
A workaround for this is to either create a named style from the default NavigationView style, or create an implicit style that uses CustomizableNavigationView as the TargetType instead of NavigationView.

How to avoid the display of multiple alert windows in Flex

I have a timer in my application. For every 30 min, it will hit the web services and fetch the data and updates the UI. The application was working fine till yesterday. Suddenly, because of some issue, the web services were not available for some time. During that period, Application displayed the RPC Error multiple times(More than 100 alert boxes) in alert window. Because of this alert boxes, my application was hanged and i was not able to do anything.
I have tried several approaches, but nothing worked.Finally, I have tried to use a flag. In all the approaches, this looked promising. so i have implemented it.Basically, in this approach whenever we open an alert we will set a flag.While opening and closing alert we will reset this flag. But it didn't work as expected. Is there any approach, which can help us in avoiding multiple alert windows.
Please help me, to fix this issue.
I would write wrapper for opening alerts, and use only this wrapper, not Alert.show in the code:
public class AlertWrapper {
private static var lastAlert:Alert;
public static function showAlert(text:String, title:String):void {
if (lastAlert) {
PopUpManager.removePopUp(lastAlert);
//or
//return; //ignore last alert
}
lastAlert = Alert.show(text, title, null, 4, onAlertClose);
}
private static function onAlertClose(event:CloseEvent):void {
lastAlert = null;
}
}
Imports are missing, but I hope the idea is clear.

MVVM Light + Blend designer view error: Cannot find resource named 'Locator'.

The application runs fine but i could not see my design in the designer view.
It says Cannot find resource named 'Locator'. Obviously, i did not change anything in the code, i just did the data binding using the data binding dialog...
anyone facing the same problem?
There are two known occurrences where this can happen.
If you change to Blend before you built the application, the DLLs are not available yet and this error can be seen. Building the application solves the issue.
There is a bug in Expression Blend where, if you are placing a user control in another user control (or Window in WPF), and the inner user control uses a global resource, the global resource cannot be found. In that case you will get the error too.
Unfortunately I do not have a workaround for the second point, as it is a Blend bug. I hope we will see a resolution for that soon, but it seems to be still there in Blend 4.
What you can do is
Ignore the error when working on the outer user control. When you work on the inner user control, you should see the design time data fine (not very satisfying I know).
Use the d:DataContext to set the design time data context in Blend temporarily.
Hopefully this helps,
Laurent
I've come up with a reasonably acceptable workaround to this problem since it doesn't appear to have been fixed in Blend 4:
In the constructor for your XAML UserControl just add the resources it needs, provided you're in design mode within Blend. This may be just the Locator, or also Styles and Converters as appropriate.
public partial class OrdersControl : UserControl
{
public OrdersControl()
{
// MUST do this BEFORE InitializeComponent()
if (DesignerProperties.GetIsInDesignMode(this))
{
if (AppDomain.CurrentDomain.BaseDirectory.Contains("Blend 4"))
{
// load styles resources
ResourceDictionary rd = new ResourceDictionary();
rd.Source = new Uri(System.IO.Path.Combine(Environment.CurrentDirectory, "Resources/Styles.xaml"), UriKind.Absolute);
Resources.MergedDictionaries.Add(rd);
// load any other resources this control needs such as Converters
Resources.Add("booleanNOTConverter", new BooleanNOTConverter());
}
}
// initialize component
this.InitializeComponent();
}
There may be some edge cases, but its working OK for me in the simple cases where before I'd get a big red error symbol. I'd LOVE to see suggestions on how to better solve this problem, but this at least allows me to animate user controls that otherwise are appearing as errors.
You could also extract out the creation of resources to App.xaml.cs:
internal static void CreateStaticResourcesForDesigner(Control element)
{
if (AppDomain.CurrentDomain.BaseDirectory.Contains("Blend 4"))
{
// load styles resources
ResourceDictionary rd = new ResourceDictionary();
rd.Source = new Uri(System.IO.Path.Combine(Environment.CurrentDirectory, "Resources/Styles.xaml"), UriKind.Absolute);
element.Resources.MergedDictionaries.Add(rd);
// load any other resources this control needs
element.Resources.Add("booleanNOTConverter", new BooleanNOTConverter());
}
}
and then in the control do this BEFORE InitializeComponent():
// create local resources
if (DesignerProperties.GetIsInDesignMode(this))
{
App.CreateStaticResourcesForDesigner(this);
}
Note: At some point in time this stopped working for me and I ended up hardcoding the path to the Styles.xaml because I got frustrated trying to figure out which directory I was in.
rd.Source = new Uri(#"R:\TFS-PROJECTS\ProjectWPF\Resources\Styles.xaml", UriKind.Absolute);
I'm sure I could find the right path with 5 minutes work, but try this if you're at your wits end like I was!
In MyUserControl.xaml, instead of:
DataContext="{Binding Main, Source={StaticResource Locator}
use:
d:DataContext="{Binding Main, Source={StaticResource Locator}
where "d" has been previously defined as:
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
The reason and workaround explained here
http://blogs.msdn.com/b/unnir/archive/2009/03/31/blend-wpf-and-resource-references.aspx
Look at (b) part of the post.
I had a similar problem with a user control resource.
I added this in my usercontrol xaml code:
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/GinaControls;component/Resources/GinaControlsColors.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
Where GinaControls is the namespace where the control class is declared and /Resources/GinaControlsColors.xaml is the project folder and xaml resource file name.
Hope this helps.
Just add this in your App.xaml.cs at the very beginning
here's my piece of code
[STATThread()]
static void main(){
App.Current.Resources.Add("Locator", new yournamespace.ViewModel.ViewModelLocator());
}
public App(){
main();
}
Make sure the Blend has opened the entire solution and NOT just the single project containing the views. I was right-clicking in Visual Studio and selecting Open In Expression Blend. To my surprize, Blend could not find the solution file, so it only opened the single project.
When I realized this, I launched Blend directly, pointed it to the solution file, and then Blend was able to find the ViewModelLocator in my view.

Flex Truncating Button Labels

First and foremost, I apologize for any vagueness in this question. At this point, I'm simply trying to get some new ideas of things to try in order to diagnose this bug.
Anyway, the problem I'm having is with an application that's using a custom moduleloader. That moduleloader has been compiled into an swc and the moduleloader is being instantiated via its namespace. This all works perfectly fine. The problem I'm encountering is specific to mx:button controls used within modules. For whatever reason, their labels are being truncated so, for example, Sign In is showing up with an ellipsis, as Sign ...
After quite a bit of fooling around I have been able to establish the following:
This problem only seems to occur within modules. If a button control is used in the main mxml, the label does not get truncated.
The button control whose label is being truncated does not have a width specified (setting its width to 100% or a specific pixel width doesn't fix the issue)
The button control is using the default padding (messing with the padding by setting left and right to 5 or any other value doesn't help matters either).
We are not using any embedded fonts so I've ruled that out as a possibility as well.
mx:CheckBox and mx:LinkButton are equally impacted by this problem although mx:CheckBox also seems to not want to show its checkbox, it just shows the truncated label.
A potential side affect of this is that attaching a dataprovider to mx:ComboBox causes the combobox control to throw a drawing error but I'm not entirely certain that it's related to the above problem.
One interesting thing I did find while perusing the net for an answer was a mention of fontContext and its relationship to IFlexModuleFactory. There's no specification for fontContext within our implementation of moduleloader so I'm not entirely certain if this could be the issue. In any case, if anyone has any ideas, it would be hugely appreciated. On the other hand, if you know exactly what ails me and can provide me with an answer, I might just wet myself with excitement. It's late. I'm tired. I NEED my Flex app to play nice.
Thanks in advance,
--Anne
Edit: To clarify what I'm looking for with this question, I really just need to know the following:
Could this issue be caused by a namespace conflict?
What else can potentially override the default behavior of labels if no CSS has been implemented?
Has anyone encountered a problem with inheritance being lost while using a custom implementation of moduleloader?
Has anyone encountered this problem or a similar problem with or without using moduleloader?
I'm not sharing any code with this question simply because I'd have to share the entire application and, unfortunately, I can't do that. Again, I'm not looking for the end all, be all solution, just some suggestions of things to look out for if anyone has any ideas.
I've been dealing with this issue myself, off and on and in various forms, for a year, and while I haven't figured out just what's causing it yet, there's clearly a mismeasurement happening somewhere along the line.
What I have been able to to, though, is work around it, essentially by subclassing button-type controls (in my case, Button, LinkButton, PopUpButton, et. al.) and assigning their textField members instances of a UITextField extension whose truncateToFit element simply returns false in all cases:
public class NonTruncatingUITextField extends UITextField
{
public function NonTruncatingUITextField ()
{
super();
}
override public function truncateToFit(s:String = null):Boolean
{
return false;
}
}
The custom component just extends Button (or whatever other button-type control is the culprit -- I've created a half-dozen or so of these myself, one for each type of control), but uses a NonTruncatingTextField as its label, where specified by the component user:
public class NonTruncatingButton extends Button
{
private var _truncateLabel:Boolean;
public function NonTruncatingButton()
{
super();
this._truncateLabel = true;
}
override protected function createChildren():void
{
if (!textField)
{
if (!_truncateLabel)
textField = new NonTruncatingUITextField();
else
textField = new UITextField();
textField.styleName = this;
addChild(DisplayObject(textField));
}
super.createChildren();
}
[Inspectable]
public function get truncateLabel():Boolean
{
return this._truncateLabel;
}
public function set truncateLabel(value:Boolean):void
{
this._truncateLabel = value;
}
}
... so then finally, in your MXML code, you'd reference the custom component thusly (in this case, I'm telling the control never to truncate its labels):
<components:NonTruncatingButton id="btn" label="Click This" truncateLabel="false" />
I agree it feels like a workaround, that the component architecture ought to handle all this more gracefully, and that it's probably something we're both overlooking, but it works; hopefully it'll solve your problem as you search for a more definitive solution. (Although personally, I'm using it as-is, and I've moved on to other things -- time's better spent elsewhere!)
Good luck -- let me know how it works out.
I've used the custom button and link button class solutions and still ran into problems - but found a workaround that's worked every time for me.
Create a css style that includes the font you'd like to use for you label. Be sure to check 'embed this font' right under the text selection dropdown. Go back and apply the style to your button (or your custom button, depending on how long you've been bashing your hear against this particular wall), and voila!
Or should be voila...
I just came across this issue and solve it this way:
<mx:LinkButton label="Some label"
updateComplete="event.target.mx_internal::getTextField().text = event.target.label"
/>;
I've had some success preventing Flex's erroneous button-label truncation by setting labelPlacement to "bottom", as in:
theButton.labelPlacement = ButtonLabelPlacement.BOTTOM;
Setting the label placement doesn't seem to help prevent truncation in some wider button sizes, but for many cases it works for me.
In cases where you can't use a bottom-aligned button label (such as when your button has a horizontally aligned icon), janusz's approach also seems to work. here's a version of janusz's .text reassignment technique in ActionScript rather than MXML:
theButton.addEventListener(FlexEvent.UPDATE_COMPLETE, function (e:FlexEvent):void {
e.target.mx_internal::getTextField().text = e.target.label;
});
The preceding code requires you to import mx_internal and FlexEvent first, as follows:
import mx.events.FlexEvent;
import mx.core.mx_internal;
And here are the results…
Before (note truncation despite ample horizontal space):
After:
The only downside to this approach is you lose the ellipsis, but in my case I considered that a welcome feature.

Resources